From 1e5b73563918c762542d5251a2fc79ec609a4547 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 22 Oct 2013 13:52:25 +0100
Subject: [PATCH] builder: Don't run virt-resize when not necessary.
If:
- the output is a regular file
- the output format is raw
- the user didn't specify the --size option
then we don't need to run virt-resize. Simply uncompress
the template directly to the output file.
(cherry picked from commit 2f3a3e308af8012501437f723471a66537ecbf64)
---
builder/builder.ml | 65 ++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 48 insertions(+), 17 deletions(-)
diff --git a/builder/builder.ml b/builder/builder.ml
index 286fd7d..6750deb 100644
--- a/builder/builder.ml
+++ b/builder/builder.ml
@@ -232,7 +232,12 @@ let main () =
Sigchecker.verify_detached sigchecker template sigfile in
- let output, size, format, delete_output_file, resize_sparse =
+ (* Plan how to create the output. This depends on:
+ * - did the user specify --output?
+ * - is the output a block device?
+ * - did the user specify --size?
+ *)
+ let output, size, format, delete_output_file, do_resize, resize_sparse =
let is_block_device file =
try (stat file).st_kind = S_BLK
with Unix_error _ -> false
@@ -259,22 +264,22 @@ let main () =
(* Dummy: The output file is never deleted in this case. *)
let delete_output_file = ref false in
- output, None, format, delete_output_file, false
+ output, None, format, delete_output_file, true, false
(* Regular file output. Note the file gets deleted. *)
| _ ->
(* Check the --size option. *)
- let size =
+ let size, do_resize =
let { Index_parser.size = default_size } = entry in
match size with
- | None -> default_size +^ headroom
+ | None -> default_size, false
| Some size ->
if size < default_size +^ headroom then (
eprintf (f_"%s: --size is too small for this disk image, minimum size is %s\n")
prog (human_size default_size);
exit 1
);
- size in
+ size, true in
(* Create the output file. *)
let output, format =
@@ -285,6 +290,14 @@ let main () =
| Some output, None -> output, "raw"
| Some output, Some format -> output, format in
+ (* If the input format != output format then we must run virt-resize. *)
+ let do_resize =
+ let input_format =
+ match entry with
+ | { Index_parser.format = Some format } -> format
+ | { Index_parser.format = None } -> "raw" in
+ if input_format <> format then true else do_resize in
+
msg (f_"Creating disk image: %s") output;
let cmd =
sprintf "qemu-img create -f %s%s %s %Ld%s"
@@ -308,25 +321,42 @@ let main () =
in
at_exit delete_file;
- output, Some size, format, delete_output_file, true in
+ output, Some size, format, delete_output_file, do_resize, true in
- let source =
- (* Uncompress it to a temporary file. *)
+ if not do_resize then (
+ (* If the user did not specify --size and the output is a regular
+ * file and the format is raw, then we just uncompress the template
+ * directly to the output file. This is fast but less flexible.
+ *)
let { Index_parser.file_uri = file_uri } = entry in
- let tmpfile = Filename.temp_file "vbsrc" ".img" in
- let cmd = sprintf "xzcat %s > %s" (quote template) (quote tmpfile) in
+ let cmd = sprintf "xzcat %s > %s" (quote template) (quote output) in
if debug then eprintf "%s\n%!" cmd;
msg (f_"Uncompressing: %s") file_uri;
let r = Sys.command cmd in
if r <> 0 then (
eprintf (f_"%s: error: failed to uncompress template\n") prog;
exit 1
- );
- unlink_on_exit tmpfile;
- tmpfile in
+ )
+ ) else (
+ (* If none of the above apply, uncompress to a temporary file and
+ * run virt-resize on the result.
+ *)
+ let tmpfile =
+ (* Uncompress it to a temporary file. *)
+ let { Index_parser.file_uri = file_uri } = entry in
+ let tmpfile = Filename.temp_file "vbsrc" ".img" in
+ let cmd = sprintf "xzcat %s > %s" (quote template) (quote tmpfile) in
+ if debug then eprintf "%s\n%!" cmd;
+ msg (f_"Uncompressing: %s") file_uri;
+ let r = Sys.command cmd in
+ if r <> 0 then (
+ eprintf (f_"%s: error: failed to uncompress template\n") prog;
+ exit 1
+ );
+ unlink_on_exit tmpfile;
+ tmpfile in
- (* Resize the source to the output file. *)
- let () =
+ (* Resize the source to the output file. *)
(match size with
| None ->
msg (f_"Running virt-resize to expand the disk")
@@ -351,13 +381,14 @@ let main () =
(match lvexpand with
| None -> ""
| Some lvexpand -> sprintf " --lv-expand %s" (quote lvexpand))
- (quote source) (quote output) in
+ (quote tmpfile) (quote output) in
if debug then eprintf "%s\n%!" cmd;
let r = Sys.command cmd in
if r <> 0 then (
eprintf (f_"%s: error: virt-resize failed\n") prog;
exit 1
- ) in
+ )
+ );
(* Now mount the output disk so we can make changes. *)
msg (f_"Opening the new disk");
--
1.8.3.1