Skip to content

Commit 5b9e892

Browse files
committed
CP-45016: Implement a new nbd proxy handler
The new http handler nbd_proxy accepts a connection from an nbd client, and acts as a proxy between the client and the nbd server of the underlying storage backend, as returned by get_nbd_server. This proxy is used in place of the old style of fd passing to tapdisks for VDI copying during storage migration, since the new nbd server from qemu-dp does not support accepting fds. This might also be used in the future for outbound storage migration for mirroring. Signed-off-by: Vincent Liu <[email protected]>
1 parent 8ebbd44 commit 5b9e892

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

ocaml/xapi/storage_migrate.ml

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -529,15 +529,15 @@ module MigrateLocal = struct
529529
let dest_vdi_url =
530530
let url' = Http.Url.of_string url in
531531
Http.Url.set_uri url'
532-
(Printf.sprintf "%s/nbd/%s/%s/%s/%s" (Http.Url.get_uri url')
532+
(Printf.sprintf "%s/nbdproxy/%s/%s/%s/%s" (Http.Url.get_uri url')
533533
(Storage_interface.Vm.string_of vm)
534534
(Storage_interface.Sr.string_of dest)
535535
(Storage_interface.Vdi.string_of dest_vdi)
536536
remote_dp
537537
)
538538
|> Http.Url.to_string
539539
in
540-
debug "copy remote NBD URL = %s" dest_vdi_url ;
540+
debug "%s copy remote NBD URL = %s" __FUNCTION__ dest_vdi_url ;
541541
let id = State.copy_id_of (sr, vdi) in
542542
debug "Persisting state for copy (id=%s)" id ;
543543
State.add id
@@ -762,7 +762,7 @@ module MigrateLocal = struct
762762
; watchdog= None
763763
}
764764
in
765-
765+
766766
State.add mirror_id (State.Send_op alm) ;
767767
debug "%s Added mirror %s to active local mirrors" __FUNCTION__ mirror_id ;
768768
(* A list of cleanup actions to perform if the operation should fail. *)
@@ -1383,6 +1383,34 @@ let nbd_handler req s ?(vm = "0") sr vdi dp =
13831383
)
13841384
(fun () -> Unix.close control_fd)
13851385

1386+
(** nbd_proxy is a http handler but will turn the http connection into an nbd connection.
1387+
It proxies the connection between the sender and the generic nbd server, as returned
1388+
by [get_nbd_server dp sr vdi vm]. *)
1389+
let nbd_proxy req s vm sr vdi dp =
1390+
debug "%s: vm=%s sr=%s vdi=%s dp=%s" __FUNCTION__ vm sr vdi dp ;
1391+
let sr, vdi = Storage_interface.(Sr.of_string sr, Vdi.of_string vdi) in
1392+
req.Http.Request.close <- true ;
1393+
let vm = Vm.of_string vm in
1394+
let path =
1395+
Storage_utils.transform_storage_exn (fun () ->
1396+
Local.DATA.MIRROR.get_nbd_server "nbd" dp sr vdi vm
1397+
)
1398+
in
1399+
debug "%s got nbd server path %s" __FUNCTION__ path ;
1400+
Http_svr.headers s (Http.http_200_ok () @ ["Transfer-encoding: nbd"]) ;
1401+
let control_fd = Unixext.open_connection_unix_fd path in
1402+
finally
1403+
(fun () ->
1404+
let s' = Unix.dup s in
1405+
let control_fd' = Unix.dup control_fd in
1406+
debug "%s: Connected; running proxy (between fds: %d and %d)" __FUNCTION__
1407+
(Unixext.int_of_file_descr control_fd')
1408+
(Unixext.int_of_file_descr s') ;
1409+
Unixext.proxy s' control_fd' ;
1410+
debug "%s: proxy exited" __FUNCTION__
1411+
)
1412+
(fun () -> Unix.close control_fd)
1413+
13861414
let with_task_and_thread ~dbg f =
13871415
let task =
13881416
Storage_task.add tasks dbg.Debug_info.log (fun task ->

ocaml/xapi/xapi_services.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,9 @@ let put_handler (req : Http.Request.t) s _ =
206206
| [""; services; "SM"; "nbd"; vm; sr; vdi; dp] when services = _services
207207
->
208208
Storage_migrate.nbd_handler req s ~vm sr vdi dp
209+
| [""; services; "SM"; "nbdproxy"; vm; sr; vdi; dp]
210+
when services = _services ->
211+
Storage_migrate.nbd_proxy req s vm sr vdi dp
209212
| _ ->
210213
Http_svr.headers s (Http.http_404_missing ~version:"1.0" ()) ;
211214
req.Http.Request.close <- true

0 commit comments

Comments
 (0)