Skip to content

Commit 8b5bdf7

Browse files
authored
Move the update_snapshot_info_dest to storage mux (xapi-project#6433)
Move the update_snapshot_info_dest to storage mux as this function just does db operations. Also rescan the SR after updaing the content_id during SXM, so that the latest content_id can be reflected in the returned vdi_info, which gets used later on in `update_snapshot_info`
2 parents 8d8aa9a + ad25956 commit 8b5bdf7

10 files changed

+118
-128
lines changed

ocaml/xapi/storage_migrate.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ module MigrateLocal = struct
278278

279279
let (module Remote) = get_remote_backend url verify_dest in
280280
(* Find the local VDI *)
281-
let local_vdi = find_local_vdi ~dbg ~sr ~vdi in
281+
let local_vdi, _ = find_vdi ~dbg ~sr ~vdi (module Local) in
282282
let mirror_id = State.mirror_id_of (sr, local_vdi.vdi) in
283283
debug "%s: Adding to active local mirrors before sending: id=%s"
284284
__FUNCTION__ mirror_id ;

ocaml/xapi/storage_migrate_helper.ml

+4-5
Original file line numberDiff line numberDiff line change
@@ -346,14 +346,13 @@ let get_remote_backend url verify_dest =
346346
end)) in
347347
(module Remote : SMAPIv2)
348348

349-
let find_local_vdi ~dbg ~sr ~vdi =
350-
(* Find the local VDI *)
351-
let vdis, _ = Local.SR.scan2 dbg sr in
349+
let find_vdi ~dbg ~sr ~vdi (module SMAPIv2 : SMAPIv2) =
350+
let vdis, _ = SMAPIv2.SR.scan2 dbg sr in
352351
match List.find_opt (fun x -> x.vdi = vdi) vdis with
353352
| None ->
354-
failwith "Local VDI not found"
353+
failwith_fmt "VDI %s not found" (Storage_interface.Vdi.string_of vdi)
355354
| Some v ->
356-
v
355+
(v, vdis)
357356

358357
(** [similar_vdis dbg sr vdi] returns a list of content_ids of vdis
359358
which are similar to the input [vdi] in [sr] *)

ocaml/xapi/storage_migrate_helper.mli

+2-1
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ module Local : SMAPIv2
261261

262262
val get_remote_backend : string -> bool -> (module SMAPIv2)
263263

264-
val find_local_vdi : dbg:string -> sr:sr -> vdi:vdi -> vdi_info
264+
val find_vdi :
265+
dbg:string -> sr:sr -> vdi:vdi -> (module SMAPIv2) -> vdi_info * vdi_info list
265266

266267
val similar_vdis : dbg:string -> sr:sr -> vdi:vdi -> uuid list

ocaml/xapi/storage_mux.ml

+64-6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ module D = Debug.Make (struct let name = "mux" end)
1919
open D
2020
open Storage_interface
2121
open Storage_mux_reg
22+
open Storage_utils
2223

2324
let s_of_sr = Storage_interface.Sr.string_of
2425

@@ -330,11 +331,32 @@ module Mux = struct
330331
Storage_migrate.update_snapshot_info_src ~dbg:(Debug_info.to_string di)
331332
~sr ~vdi ~url ~dest ~dest_vdi ~snapshot_pairs
332333

334+
let set_is_a_snapshot _context ~dbg ~sr ~vdi ~is_a_snapshot =
335+
Server_helpers.exec_with_new_task "VDI.set_is_a_snapshot"
336+
~subtask_of:(Ref.of_string dbg) (fun __context ->
337+
let vdi, _ = find_vdi ~__context sr vdi in
338+
Db.VDI.set_is_a_snapshot ~__context ~self:vdi ~value:is_a_snapshot
339+
)
340+
341+
let set_snapshot_time _context ~dbg ~sr ~vdi ~snapshot_time =
342+
let module Date = Clock.Date in
343+
Server_helpers.exec_with_new_task "VDI.set_snapshot_time"
344+
~subtask_of:(Ref.of_string dbg) (fun __context ->
345+
let vdi, _ = find_vdi ~__context sr vdi in
346+
let snapshot_time = Date.of_iso8601 snapshot_time in
347+
Db.VDI.set_snapshot_time ~__context ~self:vdi ~value:snapshot_time
348+
)
349+
350+
let set_snapshot_of _context ~dbg ~sr ~vdi ~snapshot_of =
351+
Server_helpers.exec_with_new_task "VDI.set_snapshot_of"
352+
~subtask_of:(Ref.of_string dbg) (fun __context ->
353+
let vdi, _ = find_vdi ~__context sr vdi in
354+
let snapshot_of, _ = find_vdi ~__context sr snapshot_of in
355+
Db.VDI.set_snapshot_of ~__context ~self:vdi ~value:snapshot_of
356+
)
357+
333358
let update_snapshot_info_dest () ~dbg ~sr ~vdi ~src_vdi ~snapshot_pairs =
334-
with_dbg ~name:"SR.update_snapshot_info_dest" ~dbg @@ fun di ->
335-
let module C = StorageAPI (Idl.Exn.GenClient (struct
336-
let rpc = of_sr sr
337-
end)) in
359+
with_dbg ~name:"SR.update_snapshot_info_dest" ~dbg @@ fun _di ->
338360
info
339361
"SR.update_snapshot_info_dest dbg:%s sr:%s vdi:%s ~src_vdi:%s \
340362
snapshot_pairs:%s"
@@ -348,8 +370,44 @@ module Mux = struct
348370
|> String.concat "; "
349371
|> Printf.sprintf "[%s]"
350372
) ;
351-
C.SR.update_snapshot_info_dest (Debug_info.to_string di) sr vdi src_vdi
352-
snapshot_pairs
373+
Server_helpers.exec_with_new_task "SR.update_snapshot_info_dest"
374+
~subtask_of:(Ref.of_string dbg) (fun __context ->
375+
let local_vdis, _ = scan2 () ~dbg ~sr in
376+
let find_sm_vdi ~vdi ~vdi_info_list =
377+
try List.find (fun x -> x.vdi = vdi) vdi_info_list
378+
with Not_found ->
379+
raise (Storage_error (Vdi_does_not_exist (s_of_vdi vdi)))
380+
in
381+
let assert_content_ids_match ~vdi_info1 ~vdi_info2 =
382+
if vdi_info1.content_id <> vdi_info2.content_id then
383+
raise
384+
(Storage_error
385+
(Content_ids_do_not_match
386+
(s_of_vdi vdi_info1.vdi, s_of_vdi vdi_info2.vdi)
387+
)
388+
)
389+
in
390+
(* For each (local snapshot vdi, source snapshot vdi) pair:
391+
* - Check that the content_ids are the same
392+
* - Copy snapshot_time from the source VDI to the local VDI
393+
* - Set the local VDI's snapshot_of to vdi
394+
* - Set is_a_snapshot = true for the local snapshot *)
395+
List.iter
396+
(fun (local_snapshot, src_snapshot_info) ->
397+
let local_snapshot_info =
398+
find_sm_vdi ~vdi:local_snapshot ~vdi_info_list:local_vdis
399+
in
400+
assert_content_ids_match ~vdi_info1:local_snapshot_info
401+
~vdi_info2:src_snapshot_info ;
402+
set_snapshot_time __context ~dbg ~sr ~vdi:local_snapshot
403+
~snapshot_time:src_snapshot_info.snapshot_time ;
404+
set_snapshot_of __context ~dbg ~sr ~vdi:local_snapshot
405+
~snapshot_of:vdi ;
406+
set_is_a_snapshot __context ~dbg ~sr ~vdi:local_snapshot
407+
~is_a_snapshot:true
408+
)
409+
snapshot_pairs
410+
)
353411
end
354412

355413
module VDI = struct

ocaml/xapi/storage_smapiv1.ml

+4-88
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ open D
1818
module Date = Clock.Date
1919
module XenAPI = Client.Client
2020
open Storage_interface
21-
22-
exception No_VDI
21+
open Storage_utils
2322

2423
let s_of_vdi = Vdi.string_of
2524

@@ -30,26 +29,6 @@ let with_lock = Xapi_stdext_threads.Threadext.Mutex.execute
3029
let with_dbg ~name ~dbg f =
3130
Debug_info.with_dbg ~module_name:"SMAPIv1" ~name ~dbg f
3231

33-
(* Find a VDI given a storage-layer SR and VDI *)
34-
let find_vdi ~__context sr vdi =
35-
let sr = s_of_sr sr in
36-
let vdi = s_of_vdi vdi in
37-
let open Xapi_database.Db_filter_types in
38-
let sr = Db.SR.get_by_uuid ~__context ~uuid:sr in
39-
match
40-
Db.VDI.get_records_where ~__context
41-
~expr:
42-
(And
43-
( Eq (Field "location", Literal vdi)
44-
, Eq (Field "SR", Literal (Ref.string_of sr))
45-
)
46-
)
47-
with
48-
| x :: _ ->
49-
x
50-
| _ ->
51-
raise No_VDI
52-
5332
(* Find a VDI reference given a name *)
5433
let find_content ~__context ?sr name =
5534
(* PR-1255: the backend should do this for us *)
@@ -132,32 +111,6 @@ module SMAPIv1 : Server_impl = struct
132111
let vdi_rec = Db.VDI.get_record ~__context ~self in
133112
vdi_info_of_vdi_rec __context vdi_rec
134113

135-
(* For SMAPIv1, is_a_snapshot, snapshot_time and snapshot_of are stored in
136-
* xapi's database. For SMAPIv2 they should be implemented by the storage
137-
* backend. *)
138-
let set_is_a_snapshot _context ~dbg ~sr ~vdi ~is_a_snapshot =
139-
Server_helpers.exec_with_new_task "VDI.set_is_a_snapshot"
140-
~subtask_of:(Ref.of_string dbg) (fun __context ->
141-
let vdi, _ = find_vdi ~__context sr vdi in
142-
Db.VDI.set_is_a_snapshot ~__context ~self:vdi ~value:is_a_snapshot
143-
)
144-
145-
let set_snapshot_time _context ~dbg ~sr ~vdi ~snapshot_time =
146-
Server_helpers.exec_with_new_task "VDI.set_snapshot_time"
147-
~subtask_of:(Ref.of_string dbg) (fun __context ->
148-
let vdi, _ = find_vdi ~__context sr vdi in
149-
let snapshot_time = Date.of_iso8601 snapshot_time in
150-
Db.VDI.set_snapshot_time ~__context ~self:vdi ~value:snapshot_time
151-
)
152-
153-
let set_snapshot_of _context ~dbg ~sr ~vdi ~snapshot_of =
154-
Server_helpers.exec_with_new_task "VDI.set_snapshot_of"
155-
~subtask_of:(Ref.of_string dbg) (fun __context ->
156-
let vdi, _ = find_vdi ~__context sr vdi in
157-
let snapshot_of, _ = find_vdi ~__context sr snapshot_of in
158-
Db.VDI.set_snapshot_of ~__context ~self:vdi ~value:snapshot_of
159-
)
160-
161114
module Query = struct
162115
let query _context ~dbg:_ =
163116
{
@@ -433,46 +386,9 @@ module SMAPIv1 : Server_impl = struct
433386
~dest_vdi:_ ~snapshot_pairs:_ =
434387
assert false
435388

436-
let update_snapshot_info_dest _context ~dbg ~sr ~vdi ~src_vdi:_
437-
~snapshot_pairs =
438-
Server_helpers.exec_with_new_task "SR.update_snapshot_info_dest"
439-
~subtask_of:(Ref.of_string dbg) (fun __context ->
440-
let local_vdis = scan __context ~dbg ~sr in
441-
let find_sm_vdi ~vdi ~vdi_info_list =
442-
try List.find (fun x -> x.vdi = vdi) vdi_info_list
443-
with Not_found ->
444-
raise (Storage_error (Vdi_does_not_exist (s_of_vdi vdi)))
445-
in
446-
let assert_content_ids_match ~vdi_info1 ~vdi_info2 =
447-
if vdi_info1.content_id <> vdi_info2.content_id then
448-
raise
449-
(Storage_error
450-
(Content_ids_do_not_match
451-
(s_of_vdi vdi_info1.vdi, s_of_vdi vdi_info2.vdi)
452-
)
453-
)
454-
in
455-
(* For each (local snapshot vdi, source snapshot vdi) pair:
456-
* - Check that the content_ids are the same
457-
* - Copy snapshot_time from the source VDI to the local VDI
458-
* - Set the local VDI's snapshot_of to vdi
459-
* - Set is_a_snapshot = true for the local snapshot *)
460-
List.iter
461-
(fun (local_snapshot, src_snapshot_info) ->
462-
let local_snapshot_info =
463-
find_sm_vdi ~vdi:local_snapshot ~vdi_info_list:local_vdis
464-
in
465-
assert_content_ids_match ~vdi_info1:local_snapshot_info
466-
~vdi_info2:src_snapshot_info ;
467-
set_snapshot_time __context ~dbg ~sr ~vdi:local_snapshot
468-
~snapshot_time:src_snapshot_info.snapshot_time ;
469-
set_snapshot_of __context ~dbg ~sr ~vdi:local_snapshot
470-
~snapshot_of:vdi ;
471-
set_is_a_snapshot __context ~dbg ~sr ~vdi:local_snapshot
472-
~is_a_snapshot:true
473-
)
474-
snapshot_pairs
475-
)
389+
let update_snapshot_info_dest _context ~dbg:_ ~sr:_ ~vdi:_ ~src_vdi:_
390+
~snapshot_pairs:_ =
391+
assert false
476392
end
477393

478394
module VDI = struct

ocaml/xapi/storage_smapiv1.mli

-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,4 @@ val vdi_read_write : (Sr.t * Vdi.t, bool) Hashtbl.t
2020

2121
val vdi_info_of_vdi_rec : Context.t -> API.vDI_t -> Storage_interface.vdi_info
2222

23-
val find_vdi : __context:Context.t -> Sr.t -> Vdi.t -> [`VDI] Ref.t * API.vDI_t
24-
(** Find a VDI given a storage-layer SR and VDI *)
25-
2623
module SMAPIv1 : Server_impl

ocaml/xapi/storage_smapiv1_migrate.ml

+8-23
Original file line numberDiff line numberDiff line change
@@ -162,26 +162,11 @@ module Copy = struct
162162
(Printf.sprintf "Remote SR %s not found"
163163
(Storage_interface.Sr.string_of dest)
164164
) ;
165-
let vdis = Remote.SR.scan dbg dest in
166-
let remote_vdi =
167-
try List.find (fun x -> x.vdi = dest_vdi) vdis
168-
with Not_found ->
169-
failwith
170-
(Printf.sprintf "Remote VDI %s not found"
171-
(Storage_interface.Vdi.string_of dest_vdi)
172-
)
173-
in
165+
166+
let remote_vdi, _ = find_vdi ~dbg ~sr:dest ~vdi:dest_vdi (module Remote) in
174167
let dest_content_id = remote_vdi.content_id in
175168
(* Find the local VDI *)
176-
let vdis = Local.SR.scan dbg sr in
177-
let local_vdi =
178-
try List.find (fun x -> x.vdi = vdi) vdis
179-
with Not_found ->
180-
failwith
181-
(Printf.sprintf "Local VDI %s not found"
182-
(Storage_interface.Vdi.string_of vdi)
183-
)
184-
in
169+
let local_vdi, vdis = find_vdi ~dbg ~sr ~vdi (module Local) in
185170
D.debug "copy local content_id=%s" local_vdi.content_id ;
186171
D.debug "copy remote content_id=%s" dest_content_id ;
187172
if local_vdi.virtual_size > remote_vdi.virtual_size then (
@@ -293,6 +278,10 @@ module Copy = struct
293278
(* PR-1255: XXX: this is useful because we don't have content_ids by default *)
294279
D.debug "setting local content_id <- %s" local_vdi.content_id ;
295280
Local.VDI.set_content_id dbg sr local_vdi.vdi local_vdi.content_id ;
281+
(* Re-find the VDI to get the updated content_id info *)
282+
let remote_vdi, _ =
283+
find_vdi ~dbg ~sr:dest ~vdi:dest_vdi (module Remote)
284+
in
296285
Some (Vdi_info remote_vdi)
297286
with e ->
298287
D.error "Caught %s: performing cleanup actions" (Printexc.to_string e) ;
@@ -312,11 +301,7 @@ module Copy = struct
312301
let (module Remote) = get_remote_backend url verify_dest in
313302
(* Find the local VDI *)
314303
try
315-
let vdis = Local.SR.scan dbg sr in
316-
let local_vdi =
317-
try List.find (fun x -> x.vdi = vdi) vdis
318-
with Not_found -> failwith (Printf.sprintf "Local VDI not found")
319-
in
304+
let local_vdi, _ = find_vdi ~dbg ~sr ~vdi (module Local) in
320305
try
321306
let similar_vdis = Local.VDI.similar_content dbg sr vdi in
322307
let similars = List.map (fun vdi -> vdi.content_id) similar_vdis in

ocaml/xapi/storage_utils.ml

+25
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414

1515
open Storage_interface
1616

17+
let s_of_sr = Storage_interface.Sr.string_of
18+
19+
let s_of_vdi = Storage_interface.Vdi.string_of
20+
1721
let string_of_vdi_type vdi_type =
1822
Rpc.string_of_rpc (API.rpc_of_vdi_type vdi_type)
1923

@@ -173,3 +177,24 @@ let transform_storage_exn f =
173177
(Api_errors.Server_error
174178
(Api_errors.internal_error, [Printexc.to_string e])
175179
)
180+
181+
exception No_VDI
182+
183+
let find_vdi ~__context sr vdi =
184+
let sr = s_of_sr sr in
185+
let vdi = s_of_vdi vdi in
186+
let open Xapi_database.Db_filter_types in
187+
let sr = Db.SR.get_by_uuid ~__context ~uuid:sr in
188+
match
189+
Db.VDI.get_records_where ~__context
190+
~expr:
191+
(And
192+
( Eq (Field "location", Literal vdi)
193+
, Eq (Field "SR", Literal (Ref.string_of sr))
194+
)
195+
)
196+
with
197+
| x :: _ ->
198+
x
199+
| _ ->
200+
raise No_VDI

ocaml/xapi/storage_utils.mli

+9
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,12 @@ val rpc :
6464

6565
val transform_storage_exn : (unit -> 'a) -> 'a
6666
(** [transform_storage_exn f] runs [f], rethrowing any storage error as a nice XenAPI error *)
67+
68+
exception No_VDI
69+
70+
val find_vdi :
71+
__context:Context.t
72+
-> Storage_interface.sr
73+
-> Storage_interface.vdi
74+
-> [`VDI] Ref.t * API.vDI_t
75+
(** Find a VDI given a storage-layer SR and VDI *)

ocaml/xapi/xapi_services.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ let put_handler (req : Http.Request.t) s _ =
196196
http_proxy_to_plugin req s name
197197
| [""; services; "SM"; "data"; sr; vdi] when services = _services ->
198198
let vdi, _ =
199-
Storage_smapiv1.find_vdi ~__context
199+
Storage_utils.find_vdi ~__context
200200
(Storage_interface.Sr.of_string sr)
201201
(Storage_interface.Vdi.of_string vdi)
202202
in

0 commit comments

Comments
 (0)