@@ -22,28 +22,43 @@ let receive (progress_cb : int -> unit) (unix_fd : Unix.file_descr)
2222 Vhd_qcow_parsing. run_tool qcow_tool progress_cb args ~input_fd: unix_fd
2323
2424let read_header qcow_path =
25- let args = [" read_headers" ; qcow_path] in
26- let qcow_tool = ! Xapi_globs. qcow_stream_tool in
27- let pipe_reader, pipe_writer = Unix. pipe ~cloexec: true () in
28-
2925 let progress_cb _ = () in
30- let (_ : Thread.t ) =
26+ let run_in_thread tool args pipe_writer replace_fds =
3127 Thread. create
3228 (fun () ->
3329 Xapi_stdext_pervasives.Pervasiveext. finally
3430 (fun () ->
35- Vhd_qcow_parsing. run_tool qcow_tool progress_cb args
36- ~output_fd: pipe_writer
31+ Vhd_qcow_parsing. run_tool tool progress_cb args
32+ ~output_fd: pipe_writer ~replace_fds
3733 )
3834 (fun () -> Unix. close pipe_writer)
3935 )
4036 ()
4137 in
42- pipe_reader
38+
39+ let map_pipe_reader, map_pipe_writer = Unix. pipe ~cloexec: true () in
40+ let (_ : Thread.t ) =
41+ run_in_thread ! Xapi_globs. qemu_img
42+ [" map" ; qcow_path; " --output=json" ]
43+ map_pipe_writer []
44+ in
45+
46+ let info_pipe_reader, info_pipe_writer = Unix. pipe ~cloexec: true () in
47+ let (_ : Thread.t ) =
48+ run_in_thread ! Xapi_globs. qemu_img
49+ [" info" ; qcow_path; " --output=json" ]
50+ info_pipe_writer []
51+ in
52+
53+ (map_pipe_reader, info_pipe_reader)
4354
4455let parse_header qcow_path =
45- let pipe_reader = read_header qcow_path in
46- Vhd_qcow_parsing. parse_header pipe_reader
56+ let pipe, _ = read_header qcow_path in
57+ Vhd_qcow_parsing. parse_header pipe
58+
59+ let parse_header_interval qcow_path =
60+ let pipes = read_header qcow_path in
61+ Vhd_qcow_parsing. parse_header_qemu_img pipes
4762
4863let send ?relative_to (progress_cb : int -> unit ) (unix_fd : Unix.file_descr )
4964 (path : string ) (_size : Int64.t ) =
@@ -54,7 +69,12 @@ let send ?relative_to (progress_cb : int -> unit) (unix_fd : Unix.file_descr)
5469
5570 (* If VDI is backed by QCOW, parse the header to determine nonzero clusters
5671 to avoid reading all of the raw disk *)
57- let input_fd = Result. map read_header qcow_path |> Result. to_option in
72+ let input_fds = Result. map read_header qcow_path |> Result. to_option in
73+
74+ (* TODO: If VHD headers are to be consulted as well, qcow2-to-stdout
75+ needs to properly account for cluster_bits. Currently QCOW2 export
76+ from VHD-backed VDIs will just revert to raw, without any
77+ allocation accounting. *)
5878
5979 (* Parse the header of the VDI we are diffing against as well *)
6080 let relative_to_qcow_path =
@@ -64,28 +84,60 @@ let send ?relative_to (progress_cb : int -> unit) (unix_fd : Unix.file_descr)
6484 | None ->
6585 None
6686 in
67- let diff_fd = Option. map read_header relative_to_qcow_path in
87+ let diff_fds = Option. map read_header relative_to_qcow_path in
88+
89+ let map_fd_string = Uuidx. (to_string (make () )) in
90+ let info_fd_string = Uuidx. (to_string (make () )) in
91+ let diff_map_fd_string = Uuidx. (to_string (make () )) in
92+ let diff_info_fd_string = Uuidx. (to_string (make () )) in
6893
69- let unique_string = Uuidx. (to_string (make () )) in
7094 let args =
7195 [path]
7296 @ (match relative_to with None -> [] | Some vdi -> [" --diff" ; vdi])
7397 @ ( match relative_to_qcow_path with
7498 | None ->
7599 []
76100 | Some _ ->
77- [" --json-header-diff" ; unique_string]
101+ [
102+ " --json-header-diff-map"
103+ ; diff_map_fd_string
104+ ; " --json-header-diff-info"
105+ ; diff_info_fd_string
106+ ]
78107 )
79- @ match qcow_path with Error _ -> [] | Ok _ -> [" --json-header" ]
108+ @
109+ match qcow_path with
110+ | Error _ ->
111+ []
112+ | Ok _ ->
113+ [
114+ " --json-header-map"
115+ ; map_fd_string
116+ ; " --json-header-info"
117+ ; info_fd_string
118+ ]
80119 in
81120 let qcow_tool = ! Xapi_globs. qcow_to_stdout in
82- let replace_fds = Option. map (fun fd -> [(unique_string, fd)]) diff_fd in
121+ let replace_fds =
122+ Option. map
123+ (fun (map_fd , info_fd ) ->
124+ let rfds = [(map_fd_string, map_fd); (info_fd_string, info_fd)] in
125+ match diff_fds with
126+ | Some (diff_map_fd , diff_info_fd ) ->
127+ (diff_map_fd_string, diff_map_fd)
128+ :: (diff_info_fd_string, diff_info_fd)
129+ :: rfds
130+ | None ->
131+ rfds
132+ )
133+ input_fds
134+ in
83135 Xapi_stdext_pervasives.Pervasiveext. finally
84136 (fun () ->
85- Vhd_qcow_parsing. run_tool qcow_tool progress_cb args ?input_fd
86- ~output_fd: unix_fd ?replace_fds
137+ Vhd_qcow_parsing. run_tool qcow_tool progress_cb args ~output_fd: unix_fd
138+ ?replace_fds
87139 )
88140 (fun () ->
89- Option. iter Unix. close input_fd ;
90- Option. iter Unix. close diff_fd
141+ Option. iter ( fun ( x , y ) -> Unix. close x ; Unix. close y) input_fds ;
142+ Option. iter ( fun ( x , y ) -> Unix. close x ; Unix. close y) diff_fds
91143 )
0 commit comments