[Pkg-libvirt-commits] [libguestfs] 32/179: v2v: -o rhev, -o vdsm: Fix export with multiple disks (RHBZ#1150475).

Hilko Bengen bengen at moszumanska.debian.org
Fri Oct 31 19:08:02 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 c4bad9deaf04b4329d0ecb38c007017d6330391c
Author: Richard W.M. Jones <rjones at redhat.com>
Date:   Wed Oct 8 15:00:25 2014 +0100

    v2v: -o rhev, -o vdsm: Fix export with multiple disks (RHBZ#1150475).
    
    When translating the original virt-v2v code, I misunderstood how image
    directories are created.  There is one directory under images/ per
    disk image, not one for all the disks in a single guest.
    
    Note this requires that -o vdsm uses multiple --vdsm-image-uuid
    options, one per disk image of the guest.
    
    Reported by: Alain Vondra
    Thanks: Tingting Zheng
---
 v2v/cmdline.ml      | 14 +++++++-----
 v2v/lib_ovf.ml      | 16 +++++++-------
 v2v/lib_ovf.mli     |  5 ++---
 v2v/output_rhev.ml  | 64 +++++++++++++++++++++++++++++------------------------
 v2v/output_vdsm.ml  | 56 +++++++++++++++++++++++-----------------------
 v2v/output_vdsm.mli |  2 +-
 v2v/virt-v2v.pod    |  3 ++-
 7 files changed, 84 insertions(+), 76 deletions(-)

diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
index 6b25a02..55b5447 100644
--- a/v2v/cmdline.ml
+++ b/v2v/cmdline.ml
@@ -45,7 +45,6 @@ let parse_cmdline () =
   let print_source = ref false in
   let qemu_boot = ref false in
   let quiet = ref false in
-  let vdsm_image_uuid = ref "" in
   let vdsm_vm_uuid = ref "" in
   let verbose = ref false in
   let trace = ref false in
@@ -129,6 +128,9 @@ let parse_cmdline () =
       error (f_"unknown --root option: %s") s
   in
 
+  let vdsm_image_uuids = ref [] in
+  let add_vdsm_image_uuid s = vdsm_image_uuids := s :: !vdsm_image_uuids in
+
   let vdsm_vol_uuids = ref [] in
   let add_vdsm_vol_uuid s = vdsm_vol_uuids := s :: !vdsm_vol_uuids in
 
@@ -166,7 +168,7 @@ let parse_cmdline () =
     "--quiet",   Arg.Set quiet,             ditto;
     "--root",    Arg.String set_root_choice,"ask|... " ^ s_"How to choose root filesystem";
     "--vdsm-image-uuid",
-    Arg.Set_string vdsm_image_uuid, "uuid " ^ s_"Output image UUID";
+    Arg.String add_vdsm_image_uuid, "uuid " ^ s_"Output image UUID(s)";
     "--vdsm-vol-uuid",
     Arg.String add_vdsm_vol_uuid, "uuid " ^ s_"Output vol UUID(s)";
     "--vdsm-vm-uuid",
@@ -226,7 +228,7 @@ read the man page virt-v2v(1).
   let qemu_boot = !qemu_boot in
   let quiet = !quiet in
   let root_choice = !root_choice in
-  let vdsm_image_uuid = !vdsm_image_uuid in
+  let vdsm_image_uuids = List.rev !vdsm_image_uuids in
   let vdsm_vol_uuids = List.rev !vdsm_vol_uuids in
   let vdsm_vm_uuid = !vdsm_vm_uuid in
   let verbose = !verbose in
@@ -362,10 +364,10 @@ read the man page virt-v2v(1).
         error (f_"-o vdsm: output storage was not specified, use '-os'");
       if qemu_boot then
         error (f_"-o vdsm: --qemu-boot option cannot be used in this output mode");
-      if vdsm_image_uuid = "" || vdsm_vm_uuid = "" then
-        error (f_"-o vdsm: either --vdsm-image-uuid or --vdsm-vm-uuid was not specified");
+      if vdsm_image_uuids = [] || vdsm_vol_uuids = [] || vdsm_vm_uuid = "" then
+        error (f_"-o vdsm: either --vdsm-image-uuid, --vdsm-vol-uuid or --vdsm-vm-uuid was not specified");
       let vdsm_params = {
-        Output_vdsm.image_uuid = vdsm_image_uuid;
+        Output_vdsm.image_uuids = vdsm_image_uuids;
         vol_uuids = vdsm_vol_uuids;
         vm_uuid = vdsm_vm_uuid;
       } in
diff --git a/v2v/lib_ovf.ml b/v2v/lib_ovf.ml
index afbfe7b..cbb8932 100644
--- a/v2v/lib_ovf.ml
+++ b/v2v/lib_ovf.ml
@@ -150,7 +150,7 @@ and get_ostype = function
     "Unassigned"
 
 (* Generate the .meta file associated with each volume. *)
-let create_meta_files verbose output_alloc sd_uuid image_uuid targets =
+let create_meta_files verbose output_alloc sd_uuid image_uuids targets =
   (* Note: Upper case in the .meta, mixed case in the OVF. *)
   let output_alloc_for_rhev =
     match output_alloc with
@@ -158,7 +158,7 @@ let create_meta_files verbose output_alloc sd_uuid image_uuid targets =
     | `Preallocated -> "PREALLOCATED" in
 
   List.map (
-    fun ({ target_overlay = ov } as t) ->
+    fun ({ target_overlay = ov } as t, image_uuid) ->
       let size_in_sectors =
         if ov.ov_virtual_size &^ 511L <> 0L then
           error (f_"the virtual size of the input disk %s is not an exact multiple of 512 bytes.  The virtual size is: %Ld.\n\nThis probably means something unexpected is going on, so please file a bug about this issue.")
@@ -190,11 +190,11 @@ let create_meta_files verbose output_alloc sd_uuid image_uuid targets =
       bpf "DESCRIPTION=%s\n" title;
       bpf "EOF\n";
       Buffer.contents buf
-  ) targets
+  ) (List.combine targets image_uuids)
 
 (* Create the OVF file. *)
 let rec create_ovf verbose source targets guestcaps inspect
-    output_alloc vmtype sd_uuid image_uuid vol_uuids vm_uuid =
+    output_alloc vmtype sd_uuid image_uuids vol_uuids vm_uuid =
   assert (List.length targets = List.length vol_uuids);
 
   let memsize_mb = source.s_memory /^ 1024L /^ 1024L in
@@ -278,7 +278,7 @@ let rec create_ovf verbose source targets guestcaps inspect
     ] in
 
   (* Add disks to the OVF XML. *)
-  add_disks targets guestcaps output_alloc sd_uuid image_uuid vol_uuids ovf;
+  add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf;
 
   (* Old virt-v2v ignored removable media. XXX *)
 
@@ -303,7 +303,7 @@ and append_child child = function
   | Element e -> e.e_children <- e.e_children @ [child]
 
 (* This modifies the OVF DOM, adding a section for each disk. *)
-and add_disks targets guestcaps output_alloc sd_uuid image_uuid vol_uuids ovf =
+and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf =
   let references =
     let nodes = path_to_nodes ovf ["ovf:Envelope"; "References"] in
     match nodes with
@@ -320,7 +320,7 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuid vol_uuids ovf =
 
   (* Iterate over the disks, adding them to the OVF document. *)
   iteri (
-    fun i ({ target_overlay = ov } as t, vol_uuid) ->
+    fun i ({ target_overlay = ov } as t, image_uuid, vol_uuid) ->
       let is_boot_drive = i == 0 in
 
       let fileref = image_uuid // vol_uuid in
@@ -412,7 +412,7 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuid vol_uuids ovf =
           e "rasd:last_modified_date" [] [PCData iso_time];
         ] in
       append_child item virtualhardware_section;
-  ) (List.combine targets vol_uuids)
+  ) (combine3 targets image_uuids vol_uuids)
 
 (* This modifies the OVF DOM, adding a section for each NIC. *)
 and add_networks nics guestcaps ovf =
diff --git a/v2v/lib_ovf.mli b/v2v/lib_ovf.mli
index 6c5ceab..34cb285 100644
--- a/v2v/lib_ovf.mli
+++ b/v2v/lib_ovf.mli
@@ -18,14 +18,13 @@
 
 (** Functions for dealing with OVF files. *)
 
-val create_meta_files : bool -> [`Sparse|`Preallocated] -> string -> string -> Types.target list -> string list
+val create_meta_files : bool -> [`Sparse|`Preallocated] -> string -> string list -> Types.target list -> string list
 (** Create the .meta file associated with each target.
 
-
     Note this does not write them, since output_rhev has to do a
     permissions dance when writing files.  Instead the contents of each
     file is returned (one per target), and they must be written to
     [target_file ^ ".meta"]. *)
 
-val create_ovf : bool -> Types.source -> Types.target list -> Types.guestcaps -> Types.inspect -> [`Sparse|`Preallocated] -> [`Server|`Desktop] option -> string -> string -> string list -> string -> DOM.doc
+val create_ovf : bool -> Types.source -> Types.target list -> Types.guestcaps -> Types.inspect -> [`Sparse|`Preallocated] -> [`Server|`Desktop] option -> string -> string list -> string list -> string -> DOM.doc
 (** Create the OVF file. *)
diff --git a/v2v/output_rhev.ml b/v2v/output_rhev.ml
index 7967891..9dd02ba 100644
--- a/v2v/output_rhev.ml
+++ b/v2v/output_rhev.ml
@@ -131,20 +131,17 @@ object
   val mutable esd_mp = ""
   val mutable esd_uuid = ""
 
-  (* Target image directory, UUID. *)
-  val mutable image_dir = ""
-  val mutable image_uuid = ""
-
   (* Target VM UUID. *)
   val mutable vm_uuid = ""
 
-  (* Volume UUIDs.  The length of this list will be the same as the
-   * list of targets.
+  (* Image and volume UUIDs.  The length of these lists will be the
+   * same as the list of targets.
    *)
+  val mutable image_uuids = []
   val mutable vol_uuids = []
 
-  (* Flag to indicate if the target image (image_dir) should be
-   * deleted.  This is set to false once we know the conversion was
+  (* Flag to indicate if the target image dir(s) should be deleted.
+   * This is set to false once we know the conversion was
    * successful.
    *)
   val mutable delete_target_directory = true
@@ -189,37 +186,46 @@ object
       ) in
 
     (* Create unique UUIDs for everything *)
-    image_uuid <- uuidgen ~prog ();
     vm_uuid <- uuidgen ~prog ();
-    (* Generate random volume UUIDs for each target. *)
+    (* Generate random image and volume UUIDs for each target. *)
+    image_uuids <-
+      List.map (
+        fun _ -> uuidgen ~prog ()
+      ) targets;
     vol_uuids <-
       List.map (
         fun _ -> uuidgen ~prog ()
       ) targets;
 
-    (* We need to create the target image directory so there's a place
+    (* We need to create the target image director(ies) so there's a place
      * for the main program to copy the images to.  However if image
      * conversion fails for any reason then we delete this directory.
      *)
-    image_dir <- esd_mp // esd_uuid // "images" // image_uuid;
-    Kvmuid.mkdir kvmuid_t image_dir 0o755;
+    let images_dir = esd_mp // esd_uuid // "images" in
+    List.iter (
+      fun image_uuid ->
+        let d = images_dir // image_uuid in
+        Kvmuid.mkdir kvmuid_t d 0o755
+    ) image_uuids;
     at_exit (fun () ->
       if delete_target_directory then (
-        let cmd = sprintf "rm -rf %s" (quote image_dir) in
-        Kvmuid.command kvmuid_t cmd
+        List.iter (
+          fun image_uuid ->
+            let d = images_dir // image_uuid in
+            let cmd = sprintf "rm -rf %s" d in
+            Kvmuid.command kvmuid_t cmd
+        ) image_uuids
       )
     );
-    if verbose then
-      eprintf "RHEV: image directory: %s\n%!" image_dir;
 
     (* The final directory structure should look like this:
-     *   /<MP>/<ESD_UUID>/images/<IMAGE_UUID>/
-     *      <VOL_UUID_1>        # first disk - will be created by main code
-     *      <VOL_UUID_1>.meta   # first disk
-     *      <VOL_UUID_2>        # second disk - will be created by main code
-     *      <VOL_UUID_2>.meta   # second disk
-     *      <VOL_UUID_3>        # etc
-     *      <VOL_UUID_3>.meta   #
+     *   /<MP>/<ESD_UUID>/images/
+     *      <IMAGE_UUID_1>/<VOL_UUID_1>        # first disk (gen'd by main code)
+     *      <IMAGE_UUID_1>/<VOL_UUID_1>.meta   # first disk
+     *      <IMAGE_UUID_2>/<VOL_UUID_2>        # second disk
+     *      <IMAGE_UUID_2>/<VOL_UUID_2>.meta   # second disk
+     *      <IMAGE_UUID_3>/<VOL_UUID_3>        # etc
+     *      <IMAGE_UUID_3>/<VOL_UUID_3>.meta   #
      *)
 
     (* Generate the randomly named target files (just the names).
@@ -227,19 +233,19 @@ object
      *)
     let targets =
       List.map (
-        fun ({ target_overlay = ov } as t, vol_uuid) ->
+        fun ({ target_overlay = ov } as t, image_uuid, vol_uuid) ->
           let ov_sd = ov.ov_sd in
-          let target_file = image_dir // vol_uuid in
+          let target_file = images_dir // image_uuid // vol_uuid in
 
           if verbose then
             eprintf "RHEV: will export %s to %s\n%!" ov_sd target_file;
 
           { t with target_file = target_file }
-      ) (List.combine targets vol_uuids) in
+      ) (combine3 targets image_uuids vol_uuids) in
 
     (* Generate the .meta file associated with each volume. *)
     let metas =
-      Lib_ovf.create_meta_files verbose output_alloc esd_uuid image_uuid
+      Lib_ovf.create_meta_files verbose output_alloc esd_uuid image_uuids
         targets in
     List.iter (
       fun ({ target_file = target_file }, meta) ->
@@ -273,7 +279,7 @@ object
   method create_metadata source targets guestcaps inspect =
     (* Create the metadata. *)
     let ovf = Lib_ovf.create_ovf verbose source targets guestcaps inspect
-      output_alloc vmtype esd_uuid image_uuid vol_uuids vm_uuid in
+      output_alloc vmtype esd_uuid image_uuids vol_uuids vm_uuid in
 
     (* Write it to the metadata file. *)
     let dir = esd_mp // esd_uuid // "master" // "vms" // vm_uuid in
diff --git a/v2v/output_vdsm.ml b/v2v/output_vdsm.ml
index 4023560..451bf32 100644
--- a/v2v/output_vdsm.ml
+++ b/v2v/output_vdsm.ml
@@ -27,7 +27,7 @@ open Utils
 open DOM
 
 type vdsm_params = {
-  image_uuid : string;
+  image_uuids : string list;
   vol_uuids : string list;
   vm_uuid : string;
 }
@@ -37,8 +37,9 @@ object
   inherit output verbose
 
   method as_options =
-    sprintf "-o vdsm -os %s --vdsm-image-uuid %s%s --vdsm-vm-uuid %s%s" os
-      vdsm_params.image_uuid
+    sprintf "-o vdsm -os %s%s%s --vdsm-vm-uuid %s%s" os
+      (String.concat ""
+         (List.map (sprintf " --vdsm-image-uuid %s") vdsm_params.image_uuids))
       (String.concat ""
          (List.map (sprintf " --vdsm-vol-uuid %s") vdsm_params.vol_uuids))
       vdsm_params.vm_uuid
@@ -56,9 +57,6 @@ object
   val mutable dd_mp = ""
   val mutable dd_uuid = ""
 
-  (* Target image directory. *)
-  val mutable image_dir = ""
-
   (* Target metadata directory. *)
   val mutable ovf_dir = ""
 
@@ -76,8 +74,9 @@ object
    * displaying errors there.
    *)
   method prepare_targets _ targets =
-    if List.length vdsm_params.vol_uuids <> List.length targets then
-      error (f_"the number of '--vdsm-vol-uuid' parameters passed on the command line has to match the number of guest disk images (for this guest: %d)")
+    if List.length vdsm_params.image_uuids <> List.length targets ||
+      List.length vdsm_params.vol_uuids <> List.length targets then
+      error (f_"the number of '--vdsm-image-uuid' and '--vdsm-vol-uuid' parameters passed on the command line has to match the number of guest disk images (for this guest: %d)")
         (List.length targets);
 
     let mp, uuid =
@@ -88,14 +87,15 @@ object
       eprintf "VDSM: DD mountpoint: %s\nVDSM: DD UUID: %s\n%!"
         dd_mp dd_uuid;
 
-    (* Note that VDSM has to create this directory. *)
-    image_dir <- dd_mp // dd_uuid // "images" // vdsm_params.image_uuid;
-    if not (is_directory image_dir) then
-      error (f_"image directory (%s) does not exist or is not a directory")
-        image_dir;
-
-    if verbose then
-      eprintf "VDSM: image directory: %s\n%!" image_dir;
+    (* Note that VDSM has to create all these directories. *)
+    let images_dir = dd_mp // dd_uuid // "images" in
+    List.iter (
+      fun image_uuid ->
+        let d = images_dir // image_uuid in
+        if not (is_directory d) then
+          error (f_"image directory (%s) does not exist or is not a directory")
+            d
+    ) vdsm_params.image_uuids;
 
     (* Note that VDSM has to create this directory too. *)
     ovf_dir <- dd_mp // dd_uuid // "master" // "vms" // vdsm_params.vm_uuid;
@@ -107,32 +107,32 @@ object
       eprintf "VDSM: OVF (metadata) directory: %s\n%!" ovf_dir;
 
     (* The final directory structure should look like this:
-     *   /<MP>/<ESD_UUID>/images/<IMAGE_UUID>/
-     *      <VOL_UUID_1>        # first disk - will be created by main code
-     *      <VOL_UUID_1>.meta   # first disk
-     *      <VOL_UUID_2>        # second disk - will be created by main code
-     *      <VOL_UUID_2>.meta   # second disk
-     *      <VOL_UUID_3>        # etc
-     *      <VOL_UUID_3>.meta   #
+     *   /<MP>/<ESD_UUID>/images/
+     *      <IMAGE_UUID_1>/<VOL_UUID_1>        # first disk (gen'd by main code)
+     *      <IMAGE_UUID_1>/<VOL_UUID_1>.meta   # first disk
+     *      <IMAGE_UUID_2>/<VOL_UUID_2>        # second disk
+     *      <IMAGE_UUID_2>/<VOL_UUID_2>.meta   # second disk
+     *      <IMAGE_UUID_3>/<VOL_UUID_3>        # etc
+     *      <IMAGE_UUID_3>/<VOL_UUID_3>.meta   #
      *)
 
     (* Create the target filenames. *)
     let targets =
       List.map (
-        fun ({ target_overlay = ov } as t, vol_uuid) ->
+        fun ({ target_overlay = ov } as t, image_uuid, vol_uuid) ->
           let ov_sd = ov.ov_sd in
-          let target_file = image_dir // vol_uuid in
+          let target_file = images_dir // image_uuid // vol_uuid in
 
           if verbose then
             eprintf "VDSM: will export %s to %s\n%!" ov_sd target_file;
 
           { t with target_file = target_file }
-      ) (List.combine targets vdsm_params.vol_uuids) in
+      ) (combine3 targets vdsm_params.image_uuids vdsm_params.vol_uuids) in
 
     (* Generate the .meta files associated with each volume. *)
     let metas =
       Lib_ovf.create_meta_files verbose output_alloc dd_uuid
-        vdsm_params.image_uuid targets in
+        vdsm_params.image_uuids targets in
     List.iter (
       fun ({ target_file = target_file }, meta) ->
         let meta_filename = target_file ^ ".meta" in
@@ -159,7 +159,7 @@ object
     (* Create the metadata. *)
     let ovf = Lib_ovf.create_ovf verbose source targets guestcaps inspect
       output_alloc vmtype dd_uuid
-      vdsm_params.image_uuid
+      vdsm_params.image_uuids
       vdsm_params.vol_uuids
       vdsm_params.vm_uuid in
 
diff --git a/v2v/output_vdsm.mli b/v2v/output_vdsm.mli
index 56ddf55..3ee5425 100644
--- a/v2v/output_vdsm.mli
+++ b/v2v/output_vdsm.mli
@@ -19,7 +19,7 @@
 (** [-o vdsm] target. *)
 
 type vdsm_params = {
-  image_uuid : string;                (* --vdsm-image-uuid *)
+  image_uuids : string list;          (* --vdsm-image-uuid (multiple) *)
   vol_uuids : string list;            (* --vdsm-vol-uuid (multiple) *)
   vm_uuid : string;                   (* --vdsm-vm-uuid *)
 }
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
index 7a7dd50..019fb28 100644
--- a/v2v/virt-v2v.pod
+++ b/v2v/virt-v2v.pod
@@ -483,7 +483,8 @@ control:
 
 =item *
 
-the image directory (I<--vdsm-image-uuid>)
+the image directory of each guest disk (I<--vdsm-image-uuid>) (this
+option is passed once for each guest disk)
 
 =item *
 

-- 
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