@@ -2990,14 +2990,22 @@ module Backend = struct
29902990        |  _  ->
29912991            internal_error " unexpected disk for devid %d" 
29922992
2993+       (*  parse NBD URI. We are not using the URI module because the
2994+          format is not compliant but used by qemu. Using sscanf instead 
2995+          to recognise and parse the specific URI *)  
29932996      let  is_nbd  str  = 
2994-         try  Scanf. sscanf str " nbd:unix:%s@:exportname=%s" fun  x   y  -> true )
2997+         try  Scanf. sscanf str " nbd:unix:%s@:exportname=%s" fun  _   _  -> true )
29952998        with  _  ->  false 
29962999
29973000      let  nbd  str  = 
29983001        try  Scanf. sscanf str " nbd:unix:%s@:exportname=%s" fun  x  y  -> (x, y))
29993002        with  _  ->  internal_error " %s: failed to parse '%s'" 
30003003
3004+       let  with_socket  path  f  = 
3005+         let  addr =  Unix. ADDR_UNIX  path in 
3006+         let  fd =  Unix. socket Unix. PF_UNIX  Unix. SOCK_STREAM  0  in 
3007+         finally (fun  ()  -> Unix. connect fd addr ; f fd) (fun  ()  -> Unix. close fd)
3008+ 
30013009      let  qemu_media_change  ~xs   device  _type  params  = 
30023010        debug " %s: params='%s'" 
30033011        Vbd_Common. qemu_media_change ~xs  device _type params ;
@@ -3008,6 +3016,33 @@ module Backend = struct
30083016          match  params with 
30093017          |  ""  ->
30103018              qmp_send_cmd domid Qmp. (Eject  (cd, Some  true )) |>  ignore
3019+           |  params  when  is_nbd params ->
3020+               let  path, exportname =  nbd params in 
3021+               info " %s: domain=%d NBD socket=%s" 
3022+               with_socket path @@  fun  fd  ->
3023+               let  cmd =  Qmp. (Add_fd  None ) in 
3024+               let  fd_info = 
3025+                 match  qmp_send_cmd ~send_fd: fd domid cmd with 
3026+                 |  Qmp. Fd_info  x  ->
3027+                     x
3028+                 |  other  ->
3029+                     internal_error " Unexpected result for QMP command: %s" 
3030+                       Qmp. (other |>  as_msg |>  string_of_message)
3031+               in 
3032+               let  filename = 
3033+                 Printf. sprintf " nbd:fd:%d:exportname=%s" Qmp. fdset_id
3034+                   exportname
3035+               in 
3036+               let  medium = 
3037+                 Qmp. 
3038+                   {
3039+                     medium_device=  cd
3040+                   ; medium_filename=  filename
3041+                   ; medium_format=  Some  " raw" 
3042+                   }
3043+               in 
3044+               let  cmd =  Qmp. (Blockdev_change_medium  medium) in 
3045+               qmp_send_cmd domid cmd |>  ignore
30113046          |  params  ->
30123047              Unixext. with_file params [Unix. O_RDONLY ] 0o640  @@  fun  fd_cd  ->
30133048              let  cmd =  Qmp. (Add_fd  None ) in 
0 commit comments