[Pkg-libvirt-commits] [libguestfs] 38/179: v2v: Enable trimming of data disks and non-mountpoints (RHBZ#1150701).

Hilko Bengen bengen at moszumanska.debian.org
Fri Oct 31 19:08:03 UTC 2014


This is an automated email from the git hooks/post-receive script.

bengen pushed a commit to branch experimental
in repository libguestfs.

commit e66138fbe71c24df3a282e1b23d8ed5c80f7b8c7
Author: Richard W.M. Jones <rjones at redhat.com>
Date:   Wed Oct 8 21:17:43 2014 +0100

    v2v: Enable trimming of data disks and non-mountpoints (RHBZ#1150701).
    
    This also modifies the --no-trim option so you can specify a device
    name, since this is necessary if fstrim can apply to non-mountpoints.
---
 v2v/cmdline.ml   |  4 ++--
 v2v/types.ml     |  1 +
 v2v/types.mli    |  1 +
 v2v/v2v.ml       | 66 +++++++++++++++++++++++++++++++++++++++++++++++++-------
 v2v/virt-v2v.pod |  5 +++++
 5 files changed, 67 insertions(+), 10 deletions(-)

diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
index 646d446..ab47b28 100644
--- a/v2v/cmdline.ml
+++ b/v2v/cmdline.ml
@@ -88,9 +88,9 @@ let parse_cmdline () =
       List.iter (
         fun mp ->
           if String.length mp = 0 then
-            error (f_"--no-trim: empty mountpoint");
+            error (f_"--no-trim: empty parameter");
           if mp.[0] <> '/' then
-            error (f_"--no-trim: %s: mountpoint does not begin with '/'") mp;
+            error (f_"--no-trim: %s: mountpoint/device name does not begin with '/'") mp;
       ) mps;
       no_trim := mps
   in
diff --git a/v2v/types.ml b/v2v/types.ml
index d6cf29c..ba04161 100644
--- a/v2v/types.ml
+++ b/v2v/types.ml
@@ -167,6 +167,7 @@ type inspect = {
   i_package_management : string;
   i_product_name : string;
   i_product_variant : string;
+  i_mountpoints : (string * string) list;
   i_apps : Guestfs.application2 list;
   i_apps_map : Guestfs.application2 list StringMap.t;
 }
diff --git a/v2v/types.mli b/v2v/types.mli
index b5d6a8b..863371c 100644
--- a/v2v/types.mli
+++ b/v2v/types.mli
@@ -108,6 +108,7 @@ type inspect = {
   i_package_management : string;
   i_product_name : string;
   i_product_variant : string;
+  i_mountpoints : (string * string) list;
   i_apps : Guestfs.application2 list;   (** List of packages installed. *)
   i_apps_map : Guestfs.application2 list StringMap.t;
     (** This is a map from the app name to the application object.
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index d4ba0c4..5e16477 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -256,20 +256,15 @@ let rec main () =
       printf (f_"This guest does not have virtio drivers installed.\n%!");
   );
 
+  g#umount_all ();
+
   if no_trim <> ["*"] && (do_copy || debug_overlays) then (
     (* Doing fstrim on all the filesystems reduces the transfer size
      * because unused blocks are marked in the overlay and thus do
      * not have to be copied.
      *)
     msg (f_"Mapping filesystem data to avoid copying unused and blank areas");
-    let mps = g#mountpoints () in
-    List.iter (
-      fun (_, mp) ->
-        if not (List.mem mp no_trim) then (
-          try g#fstrim mp
-          with G.Error msg -> warning ~prog (f_"%s: %s (ignored)") mp msg
-        )
-    ) mps
+    do_fstrim ~verbose g no_trim inspect;
   );
 
   msg (f_"Closing the overlay");
@@ -505,6 +500,7 @@ and inspect_source g root_choice =
     i_package_management = g#inspect_get_package_management root;
     i_product_name = g#inspect_get_product_name root;
     i_product_variant = g#inspect_get_product_variant root;
+    i_mountpoints = mps;
     i_apps = apps;
     i_apps_map = apps_map; }
 
@@ -537,6 +533,60 @@ and check_free_space mpstats =
           mp free_bytes needed_bytes
   ) mpstats
 
+(* Perform the fstrim.  The trimming bit is easy.  Dealing with the
+ * [--no-trim] parameter .. not so much.
+ *)
+and do_fstrim ~verbose g no_trim inspect =
+  (* Get all filesystems. *)
+  let fses = g#list_filesystems () in
+
+  let fses = filter_map (
+    function (_, ("unknown"|"swap")) -> None | (dev, _) -> Some dev
+  ) fses in
+
+  let fses =
+    if no_trim = [] then fses
+    else (
+      if verbose then (
+        printf "no_trim: %s\n" (String.concat " " no_trim);
+        printf "filesystems before considering no_trim: %s\n"
+          (String.concat " " fses)
+      );
+
+      (* Drop any filesystems that match a device name in the no_trim list. *)
+      let fses = List.filter (
+        fun dev ->
+          not (List.mem (g#canonical_device_name dev) no_trim)
+      ) fses in
+
+      (* Drop any mountpoints matching the no_trim list. *)
+      let dev_to_mp =
+        List.map (fun (mp, dev) -> g#canonical_device_name dev, mp)
+          inspect.i_mountpoints in
+      let fses = List.filter (
+        fun dev ->
+          try not (List.mem (List.assoc dev dev_to_mp) no_trim)
+          with Not_found -> true
+      ) fses in
+
+      if verbose then
+        printf "filesystems after considering no_trim: %s\n%!"
+          (String.concat " " fses);
+
+      fses
+    ) in
+
+  (* Trim the remaining filesystems. *)
+  List.iter (
+    fun dev ->
+      g#umount_all ();
+      let mounted = try g#mount dev "/"; true with G.Error _ -> false in
+      if mounted then (
+        try g#fstrim "/"
+        with G.Error msg -> warning ~prog (f_"%s (ignored)") msg
+      )
+  ) fses
+
 (* Estimate the space required on the target for each disk.  It is the
  * maximum space that might be required, but in reasonable cases much
  * less space would actually be needed.
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
index 019fb28..6383e82 100644
--- a/v2v/virt-v2v.pod
+++ b/v2v/virt-v2v.pod
@@ -278,6 +278,11 @@ by a comma-separated list of their mount point(s) in the guest).
 Typically you would use I<--no-trim /boot> to work around the grub bug
 mentioned above.
 
+You can also disable trimming on partitions using the libguestfs
+naming scheme for devices, eg: I<--no-trim /dev/sdb2> means do not
+trim the second partition on the second block device.  Use
+L<virt-filesystems(1)> to list filesystem names in a guest.
+
 =item B<-o disk>
 
 This is the same as I<-o local>.

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-libvirt/libguestfs.git



More information about the Pkg-libvirt-commits mailing list