<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Tue, Aug 14, 2018 at 8:29 PM Richard W.M. Jones <<a href="mailto:rjones@redhat.com">rjones@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This option prints the estimated size of the data that will be copied<br>
from the source disk.<br>
<br>
For interest, the test prints:<br>
<br>
3747840 ../test-data/phony-guests/windows.img<br>
Estimate: 3710976<br></blockquote><div><br></div><div>Why not use qemu-img measure on the overlay?</div><div><br></div><div>It gives a conservative estimate that will never fail, based on the allocated</div><div>blocks and additional metadata required for the destination file format. </div><div><br></div><div>Nir</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
---<br>
 v2v/Makefile.am                |  2 ++<br>
 v2v/<a href="http://cmdline.ml" rel="noreferrer" target="_blank">cmdline.ml</a>                 | 17 ++++++++++--<br>
 v2v/cmdline.mli                |  2 ++<br>
 v2v/test-v2v-print-estimate.sh | 47 +++++++++++++++++++++++++++++++++<br>
 v2v/<a href="http://v2v.ml" rel="noreferrer" target="_blank">v2v.ml</a>                     | 48 ++++++++++++++++++++++++++++++++++<br>
 v2v/virt-v2v.pod               | 17 ++++++++++++<br>
 6 files changed, 131 insertions(+), 2 deletions(-)<br>
<br>
diff --git a/v2v/Makefile.am b/v2v/Makefile.am<br>
index 5461055d1..2ea0dd1d5 100644<br>
--- a/v2v/Makefile.am<br>
+++ b/v2v/Makefile.am<br>
@@ -379,6 +379,7 @@ TESTS += \<br>
        test-v2v-oa-option.sh \<br>
        test-v2v-of-option.sh \<br>
        test-v2v-on-option.sh \<br>
+       test-v2v-print-estimate.sh \<br>
        test-v2v-print-source.sh \<br>
        test-v2v-sound.sh \<br>
        $(SLOW_TESTS) \<br>
@@ -534,6 +535,7 @@ EXTRA_DIST += \<br>
        test-v2v-oa-option.sh \<br>
        test-v2v-of-option.sh \<br>
        test-v2v-on-option.sh \<br>
+       test-v2v-print-estimate.sh \<br>
        test-v2v-print-source.expected \<br>
        test-v2v-print-source.sh \<br>
        test-v2v-print-source.xml \<br>
diff --git a/v2v/<a href="http://cmdline.ml" rel="noreferrer" target="_blank">cmdline.ml</a> b/v2v/<a href="http://cmdline.ml" rel="noreferrer" target="_blank">cmdline.ml</a><br>
index 5b2df3555..74cc27714 100644<br>
--- a/v2v/<a href="http://cmdline.ml" rel="noreferrer" target="_blank">cmdline.ml</a><br>
+++ b/v2v/<a href="http://cmdline.ml" rel="noreferrer" target="_blank">cmdline.ml</a><br>
@@ -33,10 +33,12 @@ type cmdline = {<br>
   debug_overlays : bool;<br>
   do_copy : bool;<br>
   in_place : bool;<br>
+  machine_readable : bool;<br>
   network_map : Networks.t;<br>
   output_alloc : output_allocation;<br>
   output_format : string option;<br>
   output_name : string option;<br>
+  print_estimate : bool;<br>
   print_source : bool;<br>
   root_choice : root_choice;<br>
 }<br>
@@ -49,6 +51,7 @@ let parse_cmdline () =<br>
   let debug_overlays = ref false in<br>
   let do_copy = ref true in<br>
   let machine_readable = ref false in<br>
+  let print_estimate = ref false in<br>
   let print_source = ref false in<br>
   let qemu_boot = ref false in<br>
<br>
@@ -235,6 +238,8 @@ let parse_cmdline () =<br>
                                     s_"Set output storage location";<br>
     [ L"password-file" ], Getopt.String ("filename", set_string_option_once "--password-file" input_password),<br>
                                     s_"Same as ‘-ip filename’";<br>
+    [ L"print-estimate" ], Getopt.Set print_estimate,<br>
+                                    s_"Estimate size of source and stop";<br>
     [ L"print-source" ], Getopt.Set print_source,<br>
                                     s_"Print source and stop";<br>
     [ L"qemu-boot" ], Getopt.Set qemu_boot, s_"Boot in qemu (-o qemu only)";<br>
@@ -330,6 +335,7 @@ read the man page virt-v2v(1).<br>
   let output_options = List.rev !output_options in<br>
   let output_password = !output_password in<br>
   let output_storage = !output_storage in<br>
+  let print_estimate = !print_estimate in<br>
   let print_source = !print_source in<br>
   let qemu_boot = !qemu_boot in<br>
   let root_choice = !root_choice in<br>
@@ -355,6 +361,12 @@ read the man page virt-v2v(1).<br>
     exit 0<br>
   );<br>
<br>
+  (* Some options cannot be used with --in-place. *)<br>
+  if in_place then (<br>
+    if print_estimate then<br>
+      error (f_"--in-place and --print-estimate cannot be used together")<br>
+  );<br>
+<br>
   (* Input transport affects whether some input options should or<br>
    * should not be used.<br>
    *)<br>
@@ -620,8 +632,9 @@ read the man page virt-v2v(1).<br>
       output_format, output_alloc in<br>
<br>
   {<br>
-    compressed; debug_overlays; do_copy; in_place; network_map;<br>
+    compressed; debug_overlays; do_copy; in_place;<br>
+    machine_readable; network_map;<br>
     output_alloc; output_format; output_name;<br>
-    print_source; root_choice;<br>
+    print_estimate; print_source; root_choice;<br>
   },<br>
   input, output<br>
diff --git a/v2v/cmdline.mli b/v2v/cmdline.mli<br>
index 25beb1c95..9b5bd4098 100644<br>
--- a/v2v/cmdline.mli<br>
+++ b/v2v/cmdline.mli<br>
@@ -23,10 +23,12 @@ type cmdline = {<br>
   debug_overlays : bool;<br>
   do_copy : bool;<br>
   in_place : bool;<br>
+  machine_readable : bool;<br>
   network_map : Networks.t;<br>
   output_alloc : Types.output_allocation;<br>
   output_format : string option;<br>
   output_name : string option;<br>
+  print_estimate : bool;<br>
   print_source : bool;<br>
   root_choice : Types.root_choice;<br>
 }<br>
diff --git a/v2v/test-v2v-print-estimate.sh b/v2v/test-v2v-print-estimate.sh<br>
new file mode 100755<br>
index 000000000..d952d1a37<br>
--- /dev/null<br>
+++ b/v2v/test-v2v-print-estimate.sh<br>
@@ -0,0 +1,47 @@<br>
+#!/bin/bash -<br>
+# libguestfs virt-v2v test script<br>
+# Copyright (C) 2018 Red Hat Inc.<br>
+#<br>
+# This program is free software; you can redistribute it and/or modify<br>
+# it under the terms of the GNU General Public License as published by<br>
+# the Free Software Foundation; either version 2 of the License, or<br>
+# (at your option) any later version.<br>
+#<br>
+# This program is distributed in the hope that it will be useful,<br>
+# but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>
+# GNU General Public License for more details.<br>
+#<br>
+# You should have received a copy of the GNU General Public License<br>
+# along with this program; if not, write to the Free Software<br>
+# Foundation, Inc., <a href="https://maps.google.com/?q=51+Franklin+Street&entry=gmail&source=g">51 Franklin Street</a>, Fifth Floor, Boston, MA 02110-1301 USA.<br>
+<br>
+# Test --print-estimate option.<br>
+<br>
+set -e<br>
+<br>
+$TEST_FUNCTIONS<br>
+skip_if_skipped<br>
+skip_unless_phony_guest windows.img<br>
+<br>
+f=test-v2v-print-estimate.out<br>
+rm -f $f<br>
+<br>
+du -s -B 1 ../test-data/phony-guests/windows.img<br>
+<br>
+$VG virt-v2v --debug-gc \<br>
+    -i libvirtxml test-v2v-print-source.xml \<br>
+    -o local -os $(pwd) \<br>
+    --print-estimate --quiet > $f<br>
+<br>
+echo -n "Estimate: "<br>
+cat $f<br>
+<br>
+# Check the output is a single number.<br>
+if [ "$(cat $f | wc -l)" -ne 1 ]; then<br>
+    echo "$0: expecting one line of output"<br>
+    exit 1<br>
+fi<br>
+grep -E '^[[:digit:]]+$' $f<br>
+<br>
+rm -f $f<br>
diff --git a/v2v/<a href="http://v2v.ml" rel="noreferrer" target="_blank">v2v.ml</a> b/v2v/<a href="http://v2v.ml" rel="noreferrer" target="_blank">v2v.ml</a><br>
index 1775200d3..e24a9adf6 100644<br>
--- a/v2v/<a href="http://v2v.ml" rel="noreferrer" target="_blank">v2v.ml</a><br>
+++ b/v2v/<a href="http://v2v.ml" rel="noreferrer" target="_blank">v2v.ml</a><br>
@@ -104,6 +104,12 @@ let rec main () =<br>
   (* Decrypt the disks. *)<br>
   inspect_decrypt g;<br>
<br>
+  (* Print source disk size estimate and stop. *)<br>
+  if cmdline.print_estimate then (<br>
+    print_source_disk_size_estimate cmdline g;<br>
+    exit 0<br>
+  );<br>
+<br>
   (* Inspection - this also mounts up the filesystems. *)<br>
   (match conversion_mode with<br>
    | Copying _ -> message (f_"Inspecting the overlay")<br>
@@ -371,6 +377,48 @@ and print_mpstat chan { mp_dev = dev; mp_path = path;<br>
   fprintf chan "  bsize=%Ld blocks=%Ld bfree=%Ld bavail=%Ld\n"<br>
     s.Guestfs.bsize s.Guestfs.blocks s.Guestfs.bfree s.Guestfs.bavail<br>
<br>
+(* Print the estimated size of the source disk(s).<br>
+ *<br>
+ * These are somewhat related to mpstats above, except that<br>
+ * we must also collect information about devices which do<br>
+ * not contain mountable filesystems and so we must assume<br>
+ * are copied completely.<br>
+ *<br>
+ * This function will unmount and mount filesystems<br>
+ * randomly, but that's OK because we exit afterwards.<br>
+ *)<br>
+and print_source_disk_size_estimate cmdline g =<br>
+  let fses = List.map fst (g#list_filesystems ()) in<br>
+<br>
+  let size =<br>
+    List.fold_left (<br>
+      fun size dev -><br>
+        g#umount_all ();<br>
+        let mounted =<br>
+          try g#mount_ro dev "/"; true<br>
+          with G.Error _ -> false in<br>
+<br>
+        let sz, what =<br>
+          if mounted then (<br>
+            let { Guestfs.bfree; blocks; bsize } = g#statvfs "/" in<br>
+            (blocks -^ bfree) *^ bsize, "filesystem"<br>
+          )<br>
+          else (<br>
+            (* Assume the full size of the filesystem will have<br>
+             * to be copied.<br>
+             *)<br>
+            g#blockdev_getsize64 dev, "device"<br>
+          ) in<br>
+<br>
+        debug "print-estimate: %s %s uses %Ld (%s)"<br>
+              what dev sz (human_size sz);<br>
+        size +^ sz<br>
+    ) 0L fses in<br>
+<br>
+  g#umount_all ();<br>
+<br>
+  printf "%Ld\n" size<br>
+<br>
 (* Conversion can fail if there is no space on the guest filesystems<br>
  * (RHBZ#1139543).  To avoid this situation, check there is some<br>
  * headroom.  Mainly we care about the root filesystem.<br>
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod<br>
index 303fe425c..80b765983 100644<br>
--- a/v2v/virt-v2v.pod<br>
+++ b/v2v/virt-v2v.pod<br>
@@ -794,6 +794,23 @@ C<root>.<br>
 You will get an error if virt-v2v is unable to mount/write to the<br>
 Export Storage Domain.<br>
<br>
+=item B<--print-estimate><br>
+<br>
+Print the estimated size of the data which will be copied from the<br>
+source disk(s) and stop.<br>
+<br>
+A single number is printed on stdout which is the estimated size of<br>
+data that will be copied, in bytes.<br>
+<br>
+This estimate is the sum across all disks, because guest features such<br>
+as LVM and MD means that it is not meaningful to provide separate<br>
+estimates for each disk.  The size does not include deleted files and<br>
+empty space in the source, but it cannot detect used-but-zero space<br>
+and so it usually overestimates.<br>
+<br>
+You usually want to use this option in conjunction with the I<--quiet><br>
+option so that the result is not mixed in with standard messages.<br>
+<br>
 =item B<--print-source><br>
<br>
 Print information about the source guest and stop.  This option is<br>
-- <br>
2.18.0 </blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
_______________________________________________<br>
Libguestfs mailing list<br>
<a href="mailto:Libguestfs@redhat.com" target="_blank">Libguestfs@redhat.com</a><br>
<a href="https://www.redhat.com/mailman/listinfo/libguestfs" rel="noreferrer" target="_blank">https://www.redhat.com/mailman/listinfo/libguestfs</a></blockquote></div></div>