[Libguestfs] [PATCH v2] v2v: Add --print-estimate option to print copy size estimate.

Richard W.M. Jones rjones at redhat.com
Thu Aug 16 12:51:36 UTC 2018


This option prints the estimated size of the data that will be copied
from the source disk.

Currently this overestimates by the size of the qcow2 header, but for
real disk images that doesn't matter much.

For example:

$ virt-builder fedora-27
$ virt-v2v -i disk fedora-27.img -o null --machine-readable --print-estimate
[...]
virt-v2v: This guest has virtio drivers installed.
[  44.0] Mapping filesystem data to avoid copying unused and blank areas
[  44.5] Closing the overlay
{ "disks": [
{
    "required": 1047920640,
    "fully-allocated": 6443696128
}
] }
---
 v2v/Makefile.am                |  2 ++
 v2v/cmdline.ml                 | 17 +++++++++++--
 v2v/cmdline.mli                |  2 ++
 v2v/test-v2v-print-estimate.sh | 45 ++++++++++++++++++++++++++++++++++
 v2v/v2v.ml                     | 26 ++++++++++++++++++++
 v2v/virt-v2v.pod               | 19 ++++++++++++++
 6 files changed, 109 insertions(+), 2 deletions(-)

diff --git a/v2v/Makefile.am b/v2v/Makefile.am
index 5461055d1..2ea0dd1d5 100644
--- a/v2v/Makefile.am
+++ b/v2v/Makefile.am
@@ -379,6 +379,7 @@ TESTS += \
 	test-v2v-oa-option.sh \
 	test-v2v-of-option.sh \
 	test-v2v-on-option.sh \
+	test-v2v-print-estimate.sh \
 	test-v2v-print-source.sh \
 	test-v2v-sound.sh \
 	$(SLOW_TESTS) \
@@ -534,6 +535,7 @@ EXTRA_DIST += \
 	test-v2v-oa-option.sh \
 	test-v2v-of-option.sh \
 	test-v2v-on-option.sh \
+	test-v2v-print-estimate.sh \
 	test-v2v-print-source.expected \
 	test-v2v-print-source.sh \
 	test-v2v-print-source.xml \
diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
index 5b2df3555..74cc27714 100644
--- a/v2v/cmdline.ml
+++ b/v2v/cmdline.ml
@@ -33,10 +33,12 @@ type cmdline = {
   debug_overlays : bool;
   do_copy : bool;
   in_place : bool;
+  machine_readable : bool;
   network_map : Networks.t;
   output_alloc : output_allocation;
   output_format : string option;
   output_name : string option;
+  print_estimate : bool;
   print_source : bool;
   root_choice : root_choice;
 }
@@ -49,6 +51,7 @@ let parse_cmdline () =
   let debug_overlays = ref false in
   let do_copy = ref true in
   let machine_readable = ref false in
+  let print_estimate = ref false in
   let print_source = ref false in
   let qemu_boot = ref false in
 
@@ -235,6 +238,8 @@ let parse_cmdline () =
                                     s_"Set output storage location";
     [ L"password-file" ], Getopt.String ("filename", set_string_option_once "--password-file" input_password),
                                     s_"Same as ‘-ip filename’";
+    [ L"print-estimate" ], Getopt.Set print_estimate,
+                                    s_"Estimate size of source and stop";
     [ L"print-source" ], Getopt.Set print_source,
                                     s_"Print source and stop";
     [ L"qemu-boot" ], Getopt.Set qemu_boot, s_"Boot in qemu (-o qemu only)";
@@ -330,6 +335,7 @@ read the man page virt-v2v(1).
   let output_options = List.rev !output_options in
   let output_password = !output_password in
   let output_storage = !output_storage in
+  let print_estimate = !print_estimate in
   let print_source = !print_source in
   let qemu_boot = !qemu_boot in
   let root_choice = !root_choice in
@@ -355,6 +361,12 @@ read the man page virt-v2v(1).
     exit 0
   );
 
+  (* Some options cannot be used with --in-place. *)
+  if in_place then (
+    if print_estimate then
+      error (f_"--in-place and --print-estimate cannot be used together")
+  );
+
   (* Input transport affects whether some input options should or
    * should not be used.
    *)
@@ -620,8 +632,9 @@ read the man page virt-v2v(1).
       output_format, output_alloc in
 
   {
-    compressed; debug_overlays; do_copy; in_place; network_map;
+    compressed; debug_overlays; do_copy; in_place;
+    machine_readable; network_map;
     output_alloc; output_format; output_name;
-    print_source; root_choice;
+    print_estimate; print_source; root_choice;
   },
   input, output
diff --git a/v2v/cmdline.mli b/v2v/cmdline.mli
index 25beb1c95..9b5bd4098 100644
--- a/v2v/cmdline.mli
+++ b/v2v/cmdline.mli
@@ -23,10 +23,12 @@ type cmdline = {
   debug_overlays : bool;
   do_copy : bool;
   in_place : bool;
+  machine_readable : bool;
   network_map : Networks.t;
   output_alloc : Types.output_allocation;
   output_format : string option;
   output_name : string option;
+  print_estimate : bool;
   print_source : bool;
   root_choice : Types.root_choice;
 }
diff --git a/v2v/test-v2v-print-estimate.sh b/v2v/test-v2v-print-estimate.sh
new file mode 100755
index 000000000..bbc810151
--- /dev/null
+++ b/v2v/test-v2v-print-estimate.sh
@@ -0,0 +1,45 @@
+#!/bin/bash -
+# libguestfs virt-v2v test script
+# Copyright (C) 2018 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# Test --print-estimate option.
+
+set -e
+
+$TEST_FUNCTIONS
+skip_if_skipped
+skip_unless_phony_guest windows.img
+
+f=test-v2v-print-estimate.out
+rm -f $f
+
+echo "Actual:"
+du -s -B 1 ../test-data/phony-guests/windows.img
+
+$VG virt-v2v --debug-gc \
+    -i libvirtxml test-v2v-print-source.xml \
+    -o local -os $(pwd) \
+    --print-estimate --quiet > $f
+
+echo "Estimate:"
+cat $f
+
+# Check the output looks reasonable.  This is not a very good test XXX.
+grep "required" $f
+grep "fully allocated size" $f
+
+rm -f $f
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 1775200d3..23dea0012 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -156,6 +156,12 @@ let rec main () =
   (match conversion_mode with
    | In_place -> ()
    | Copying overlays ->
+      (* Print copy size estimate and stop. *)
+      if cmdline.print_estimate then (
+        print_copy_size_estimate cmdline overlays;
+        exit 0
+      );
+
       message (f_"Assigning disks to buses");
       let target_buses =
         Target_bus_assignment.target_bus_assignment source guestcaps in
@@ -371,6 +377,26 @@ and print_mpstat chan { mp_dev = dev; mp_path = path;
   fprintf chan "  bsize=%Ld blocks=%Ld bfree=%Ld bavail=%Ld\n"
     s.Guestfs.bsize s.Guestfs.blocks s.Guestfs.bfree s.Guestfs.bavail
 
+(* Print the estimated size that will be copied for each disk. *)
+and print_copy_size_estimate cmdline overlays =
+  let json = cmdline.machine_readable in
+  if json then printf "{ \"disks\": [\n%!";
+  List.iteri (
+    fun i { ov_overlay_file } ->
+      if json && i > 0 then printf ",\n%!";
+      let cmd =
+        [ Guestfs_config.qemu_img; "measure";
+          (* For use of -O qcow2 here, see this thread:
+           * https://www.redhat.com/archives/libguestfs/2018-August/thread.html#00142
+           *)
+          "-f"; "qcow2"; "-O"; "qcow2";
+          "--output=" ^ (if json then "json" else "human");
+          ov_overlay_file ] in
+      if run_command cmd <> 0 then
+        error (f_"qemu-img measure failed, see earlier errors");
+  ) overlays;
+  if json then printf "] }%!\n"
+
 (* Conversion can fail if there is no space on the guest filesystems
  * (RHBZ#1139543).  To avoid this situation, check there is some
  * headroom.  Mainly we care about the root filesystem.
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
index 303fe425c..53529c95c 100644
--- a/v2v/virt-v2v.pod
+++ b/v2v/virt-v2v.pod
@@ -794,6 +794,25 @@ C<root>.
 You will get an error if virt-v2v is unable to mount/write to the
 Export Storage Domain.
 
+=item B<--print-estimate>
+
+Print the estimated size of the data which will be copied from the
+source disk(s) and stop.  The estimate is produced by the
+L<qemu-img(1)> C<measure> command, so the output fields are the same
+as for that command.
+
+The default is to produce human readable output.  For parsable JSON
+output use:
+
+ virt-v2v [-i options ...] -o null --print-estimate --machine-readable
+
+and throw away all lines sent to stdout before C</^{ "disks"/>.
+
+When using this option you must specify an output mode.  This is
+because virt-v2v has to perform the conversion in order to print the
+estimate, and the conversion depends on the output mode.  Using
+I<-o null> should be safe for most purposes.
+
 =item B<--print-source>
 
 Print information about the source guest and stop.  This option is
-- 
2.18.0




More information about the Libguestfs mailing list