Skip to content

Commit 99b3756

Browse files
committed
[qcow-tool] add qcow as supported format
This patch allows to pass "qcow2" as a supported format when calling VDI import/export. Currently we should reach unimplemented qcow tool wrapper if we are using "qcow2"" format. Signed-off-by: Guillaume <[email protected]>
1 parent a7939ca commit 99b3756

File tree

8 files changed

+104
-11
lines changed

8 files changed

+104
-11
lines changed

ocaml/vhd-tool/src/impl.ml

+4-2
Original file line numberDiff line numberDiff line change
@@ -1313,7 +1313,7 @@ let serve common_options source source_fd source_format source_protocol
13131313
protocol_of_string (require "source-protocol" source_protocol)
13141314
in
13151315

1316-
let supported_formats = ["raw"; "vhd"] in
1316+
let supported_formats = ["raw"; "vhd"; "qcow2"] in
13171317
if not (List.mem source_format supported_formats) then
13181318
failwith (Printf.sprintf "%s is not a supported format" source_format) ;
13191319
let supported_formats = ["raw"] in
@@ -1351,7 +1351,9 @@ let serve common_options source source_fd source_format source_protocol
13511351
endpoint_of_string source
13521352
| Some fd ->
13531353
return
1354-
(File_descr (Lwt_unix.of_unix_file_descr (file_descr_of_int fd)))
1354+
( Printf.fprintf stderr "GTNDEBUG: source fd is %d" fd ;
1355+
File_descr (Lwt_unix.of_unix_file_descr (file_descr_of_int fd))
1356+
)
13551357
)
13561358
>>= fun source_endpoint ->
13571359
( match source_endpoint with

ocaml/xapi-consts/api_errors.ml

+3
Original file line numberDiff line numberDiff line change
@@ -1398,3 +1398,6 @@ let telemetry_next_collection_too_late =
13981398
let illegal_in_fips_mode = add_error "ILLEGAL_IN_FIPS_MODE"
13991399

14001400
let too_many_groups = add_error "TOO_MANY_GROUPS"
1401+
1402+
let unimplemented_in_qcow_tool_wrapper =
1403+
add_error "UNIMPLEMENTED_IN_QCOW_TOOL_WRAPPER"

ocaml/xapi/export_raw_vdi.ml

+11-6
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,16 @@ let localhost_handler rpc session_id vdi (req : Http.Request.t)
4747
let copy base_path path size =
4848
try
4949
debug "Copying VDI contents..." ;
50-
Vhd_tool_wrapper.send ?relative_to:base_path
51-
(Vhd_tool_wrapper.update_task_progress __context)
52-
"none"
53-
(Importexport.Format.to_string format)
54-
s path size "" ;
50+
if format = Qcow then
51+
Qcow_tool_wrapper.send
52+
(Qcow_tool_wrapper.update_task_progress __context)
53+
s path size
54+
else
55+
Vhd_tool_wrapper.send ?relative_to:base_path
56+
(Vhd_tool_wrapper.update_task_progress __context)
57+
"none"
58+
(Importexport.Format.to_string format)
59+
s path size "" ;
5560
debug "Copying VDI complete."
5661
with Unix.Unix_error (Unix.EIO, _, _) ->
5762
raise
@@ -73,7 +78,7 @@ let localhost_handler rpc session_id vdi (req : Http.Request.t)
7378
in
7479
Http_svr.headers s headers ;
7580
match format with
76-
| Raw | Vhd ->
81+
| Qcow | Raw | Vhd ->
7782
let size = Db.VDI.get_virtual_size ~__context ~self:vdi in
7883
if format = Vhd && size > Constants.max_vhd_size then
7984
raise

ocaml/xapi/import_raw_vdi.ml

+2-1
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,12 @@ let localhost_handler rpc session_id vdi_opt (req : Request.t)
158158
in
159159
Http_svr.headers s headers ;
160160
( match format with
161-
| Raw | Vhd ->
161+
| Raw | Vhd | Qcow ->
162162
let prezeroed =
163163
not
164164
(Sm_fs_ops.must_write_zeroes_into_new_vdi ~__context vdi)
165165
in
166+
debug "GTNDEBUG: we are receiving Raw, Vhd or Qcow file" ;
166167
Sm_fs_ops.with_block_attached_device __context rpc
167168
session_id vdi `RW (fun path ->
168169
if chunked then

ocaml/xapi/importexport.ml

+14-2
Original file line numberDiff line numberDiff line change
@@ -428,9 +428,17 @@ let sr_of_req ~__context (req : Http.Request.t) =
428428
None
429429

430430
module Format = struct
431-
type t = Raw | Vhd | Tar
431+
type t = Raw | Vhd | Tar | Qcow
432432

433-
let to_string = function Raw -> "raw" | Vhd -> "vhd" | Tar -> "tar"
433+
let to_string = function
434+
| Raw ->
435+
"raw"
436+
| Vhd ->
437+
"vhd"
438+
| Tar ->
439+
"tar"
440+
| Qcow ->
441+
"qcow2"
434442

435443
let of_string x =
436444
match String.lowercase_ascii x with
@@ -440,6 +448,8 @@ module Format = struct
440448
Some Vhd
441449
| "tar" ->
442450
Some Tar
451+
| "qcow2" ->
452+
Some Qcow
443453
| _ ->
444454
None
445455

@@ -455,6 +465,8 @@ module Format = struct
455465
"application/vhd"
456466
| Tar ->
457467
"application/x-tar"
468+
| Qcow ->
469+
"application/x-qemu-disk"
458470

459471
let _key = "format"
460472

ocaml/xapi/qcow_tool_wrapper.ml

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
(*
2+
* Copyright (C) 2025 Vates.
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU Lesser General Public License as published
6+
* by the Free Software Foundation; version 2.1 only. with the special
7+
* exception on linking described in file LICENSE.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Lesser General Public License for more details.
13+
*)
14+
15+
module D = Debug.Make (struct let name = "qcow_tool_wrapper" end)
16+
17+
open D
18+
19+
let unimplemented () =
20+
raise
21+
(Api_errors.Server_error (Api_errors.unimplemented_in_qcow_tool_wrapper, []))
22+
23+
let run_qcow_tool (progress_cb : int -> unit) (args : string list)
24+
(ufd : Unix.file_descr) =
25+
let qcow_tool = !Xapi_globs.qcow_tool in
26+
info "Executing %s %s" qcow_tool (String.concat " " args) ;
27+
let open Forkhelpers in
28+
let pipe_read, pipe_write = Unix.pipe () in
29+
Xapi_stdext_pervasives.Pervasiveext.finally
30+
(fun () ->
31+
match
32+
with_logfile_fd "qcow-tool" (fun log_fd ->
33+
let ufd_str = Uuidx.(to_string (make ())) in
34+
let pid =
35+
safe_close_and_exec None (Some pipe_write) (Some log_fd)
36+
[(ufd_str, ufd)]
37+
qcow_tool args
38+
in
39+
let _, status = waitpid pid in
40+
if status <> Unix.WEXITED 0 then (
41+
error "qcow-tool failed, returning VDI_IO_ERROR" ;
42+
raise
43+
(Api_errors.Server_error
44+
(Api_errors.vdi_io_error, ["Device I/O errors"])
45+
)
46+
)
47+
)
48+
with
49+
| Success (out, _) ->
50+
debug "%s" out
51+
| Failure (out, e) ->
52+
error "qcow-tool output: %s" out ;
53+
raise e
54+
)
55+
(fun () -> List.iter Unix.close [pipe_read; pipe_write])
56+
57+
let update_task_progress (__context : Context.t) (x : int) =
58+
TaskHelper.set_progress ~__context (float_of_int x /. 100.)
59+
60+
let send (progress_cb : int -> unit) (unix_fd : Unix.file_descr) (path : string)
61+
(size : Int64.t) =
62+
debug "Qcow send called with a size of %Ld and path equal to %s" size path ;
63+
let _ = progress_cb in
64+
let _ = unix_fd in
65+
run_qcow_tool progress_cb ["stream"] unix_fd

ocaml/xapi/vhd_tool_wrapper.ml

+2
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ let send progress_cb ?relative_to (protocol : string) (dest_format : string)
193193
(s : Unix.file_descr) (path : string) (size : Int64.t) (prefix : string) =
194194
let s' = Uuidx.(to_string (make ())) in
195195
let source_format, source =
196+
debug "GTNDEBUG: get_nbd_device %s" path ;
197+
debug "GTNDEBUG: s' is %s" s' ;
196198
match (Stream_vdi.get_nbd_device path, vhd_of_device path, relative_to) with
197199
| Some (nbd_server, exportname), _, None ->
198200
( "nbdhybrid"

ocaml/xapi/xapi_globs.ml

+3
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,8 @@ let sparse_dd = ref "sparse_dd"
804804

805805
let vhd_tool = ref "vhd-tool"
806806

807+
let qcow_tool = ref "qcow-tool"
808+
807809
let fence = ref "fence"
808810

809811
let host_bugreport_upload = ref "host-bugreport-upload"
@@ -1660,6 +1662,7 @@ module Resources = struct
16601662
)
16611663
; ("sparse_dd", sparse_dd, "Path to sparse_dd")
16621664
; ("vhd-tool", vhd_tool, "Path to vhd-tool")
1665+
; ("qcow-tool", qcow_tool, "Path to qcow-tool")
16631666
; ("fence", fence, "Path to fence binary, used for HA host fencing")
16641667
; ( "host-bugreport-upload"
16651668
, host_bugreport_upload

0 commit comments

Comments
 (0)