[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