v2v: Preserve VM Generation ID (RHBZ#1598350).

virt-v2v moves guests, it doesn't clone them.  Therefore we should try
to preserve the VM Generation ID (genid) as much as possible.

This has the ability to read the genid from VMware VMX files and
libvirt XML (but note RHBZ#1598348).  It can also write the genid to
libvirt (‘-o libvirt’, ‘-o local’) and QEMU (‘-o qemu’).

We are missing support currently for all OVF-based formats (hence
‘-i ova’, and all oVirt/RHV output modes).  It's unclear where we
would store the genid in this format.  oVirt does not yet support
genid (see RHBZ#1118825).
This commit is contained in:
Richard W.M. Jones
2018-07-05 11:21:57 +01:00
parent 9a25ac6b4e
commit b11b870166
24 changed files with 62 additions and 0 deletions

View File

@@ -40,6 +40,11 @@ let create_libvirt_xml ?pool source target_buses guestcaps
e "name" [] [PCData source.s_name];
];
(match source.s_genid with
| None -> ()
| Some genid -> List.push_back body (e "genid" [] [PCData genid])
);
let memory_k = source.s_memory /^ 1024L in
List.push_back_list body [
e "memory" ["unit", "KiB"] [PCData (Int64.to_string memory_k)];

View File

@@ -80,6 +80,7 @@ class input_disk input_format disk = object
let source = {
s_hypervisor = UnknownHV;
s_name = name; s_orig_name = name;
s_genid = None;
s_memory = 2048L *^ 1024L *^ 1024L; (* 2048 MB *)
s_vcpu = 1; (* 1 vCPU is a safe default *)
s_cpu_vendor = None;

View File

@@ -189,6 +189,7 @@ class input_ova ova = object
s_hypervisor = VMware;
s_name = name;
s_orig_name = name;
s_genid = None; (* XXX *)
s_memory = memory;
s_vcpu = vcpu;
s_cpu_vendor = None;

View File

@@ -426,6 +426,28 @@ object
| File filename -> name_from_disk filename
| SSH uri -> name_from_disk (path_of_uri uri) in
let genid =
(* See: https://lists.nongnu.org/archive/html/qemu-devel/2018-07/msg02019.html *)
let genid_lo = Parse_vmx.get_int64 vmx ["vm"; "genid"]
and genid_hi = Parse_vmx.get_int64 vmx ["vm"; "genidX"] in
match genid_lo, genid_hi with
| None, None | Some _, None | None, Some _ ->
None
| Some lo, Some hi ->
(* The actual mapping from the two integers to the UUID
* (as defined by qemu and used by libvirt) is very complex.
* This code was determined empirically. See also:
* https://lists.nongnu.org/archive/html/qemu-devel/2018-07/msg01505.html
*)
let sub = String.sub (sprintf "%016Lx%016Lx" lo hi) in
let uuid =
sub 8 8 ^ "-" ^
sub 4 4 ^ "-" ^
sub 0 4 ^ "-" ^
sub 30 2 ^ sub 28 2 ^ "-" ^
sub 26 2 ^ sub 24 2 ^ sub 22 2 ^ sub 20 2 ^ sub 18 2 ^ sub 16 2 in
Some uuid in
let memory_mb =
match Parse_vmx.get_int64 vmx ["memSize"] with
| None -> 32_L (* default is really 32 MB! *)
@@ -483,6 +505,7 @@ object
let source = {
s_hypervisor = VMware;
s_name = name;
s_genid = genid;
s_orig_name = name;
s_memory = memory;
s_vcpu = vcpu;

View File

@@ -80,6 +80,13 @@ object
flag "-no-user-config"; flag "-nodefaults";
arg "-name" source.s_name;
(match source.s_genid with
| None -> ()
| Some genid ->
arg_list "-device" ["vmgenid"; sprintf "guid=%s" genid; "id=vmgenid0"]
);
arg_list "-machine" (if machine_q35 then ["q35"] else [] @
if smm then ["smm=on"] else [] @
["accel=kvm:tcg"]);

View File

@@ -90,6 +90,10 @@ let parse_libvirt_xml ?conn xml =
| None | Some "" ->
error (f_"in the libvirt XML metadata, <name> is missing or empty")
| Some s -> s in
let genid =
match xpath_string "/domain/genid/text()" with
| None | Some "" -> None
| Some _ as s -> s in
let memory =
Option.default (1024L *^ 1024L) (xpath_int64 "/domain/memory/text()") in
let memory = memory *^ 1024L in
@@ -481,6 +485,7 @@ let parse_libvirt_xml ?conn xml =
({
s_hypervisor = hypervisor;
s_name = name; s_orig_name = name;
s_genid = genid;
s_memory = memory;
s_vcpu = vcpu;
s_cpu_vendor = cpu_vendor;

View File

@@ -2,6 +2,7 @@ Source guest information (--print-source option):
source name: 2K8R2EESP1_2_Medium
hypervisor type: vmware
VM genid:
memory: 1073741824 (bytes)
nr vCPUs: 1
CPU vendor:

View File

@@ -2,6 +2,7 @@ Source guest information (--print-source option):
source name: 2K8R2EESP1_2_Medium
hypervisor type: vmware
VM genid:
memory: 1073741824 (bytes)
nr vCPUs: 1
CPU vendor:

View File

@@ -2,6 +2,7 @@ Source guest information (--print-source option):
source name: 2K8R2EESP1_2_Medium
hypervisor type: vmware
VM genid:
memory: 1073741824 (bytes)
nr vCPUs: 1
CPU vendor:

View File

@@ -2,6 +2,7 @@ Source guest information (--print-source option):
source name: 2K8R2EESP1_2_Medium
hypervisor type: vmware
VM genid:
memory: 1073741824 (bytes)
nr vCPUs: 1
CPU vendor:

View File

@@ -2,6 +2,7 @@ Source guest information (--print-source option):
source name: 2K8R2EESP1_2_Medium
hypervisor type: vmware
VM genid:
memory: 1073741824 (bytes)
nr vCPUs: 1
CPU vendor:

View File

@@ -2,6 +2,7 @@ Source guest information (--print-source option):
source name: 2K8R2EESP1_2_Medium
hypervisor type: vmware
VM genid:
memory: 1073741824 (bytes)
nr vCPUs: 1
CPU vendor:

View File

@@ -2,6 +2,7 @@ Source guest information (--print-source option):
source name: 2K8R2EESP1_2_Medium
hypervisor type: vmware
VM genid:
memory: 1073741824 (bytes)
nr vCPUs: 1
CPU vendor:

View File

@@ -2,6 +2,7 @@ Source guest information (--print-source option):
source name: 2K8R2EESP1_2_Medium
hypervisor type: vmware
VM genid:
memory: 1073741824 (bytes)
nr vCPUs: 1
CPU vendor:

View File

@@ -2,6 +2,7 @@ Source guest information (--print-source option):
source name: 2K8R2EESP1_2_Medium
hypervisor type: vmware
VM genid:
memory: 1073741824 (bytes)
nr vCPUs: 1
CPU vendor:

View File

@@ -2,6 +2,7 @@ Source guest information (--print-source option):
source name: 2K8R2EESP1_2_Medium
hypervisor type: vmware
VM genid:
memory: 1073741824 (bytes)
nr vCPUs: 1
CPU vendor:

View File

@@ -3,6 +3,7 @@ Source guest information (--print-source option):
source name: BZ1308535_21disks
hypervisor type: vmware
VM genid:
memory: 2147483648 (bytes)
nr vCPUs: 1
CPU vendor:

View File

@@ -3,6 +3,7 @@ Source guest information (--print-source option):
source name: Fedora 20
hypervisor type: vmware
VM genid:
memory: 2147483648 (bytes)
nr vCPUs: 1
CPU vendor:

View File

@@ -3,6 +3,7 @@ Source guest information (--print-source option):
source name: RHEL 7.1 UEFI
hypervisor type: vmware
VM genid:
memory: 2147483648 (bytes)
nr vCPUs: 1
CPU vendor:

View File

@@ -3,6 +3,7 @@ Source guest information (--print-source option):
source name: Windows 7 x64
hypervisor type: vmware
VM genid:
memory: 2147483648 (bytes)
nr vCPUs: 1
CPU vendor:

View File

@@ -3,6 +3,7 @@ Source guest information (--print-source option):
source name: MSEdge - Win10_preview
hypervisor type: vmware
VM genid: 8312995e-57b8-f814-4013-c1ba795f05ba
memory: 2147483648 (bytes)
nr vCPUs: 1
CPU vendor:

View File

@@ -1,5 +1,6 @@
source name: windows
hypervisor type: kvm
VM genid:
memory: 1073741824 (bytes)
nr vCPUs: 64
CPU vendor: Intel

View File

@@ -28,6 +28,7 @@ type source = {
s_hypervisor : source_hypervisor;
s_name : string;
s_orig_name : string;
s_genid : string option;
s_memory : int64;
s_vcpu : int;
s_cpu_vendor : string option;
@@ -109,6 +110,7 @@ and source_cpu_topology = {
let rec string_of_source s =
sprintf " source name: %s
hypervisor type: %s
VM genid: %s
memory: %Ld (bytes)
nr vCPUs: %d
CPU vendor: %s
@@ -128,6 +130,7 @@ NICs:
"
s.s_name
(string_of_source_hypervisor s.s_hypervisor)
(Option.default "" s.s_genid)
s.s_memory
s.s_vcpu
(Option.default "" s.s_cpu_vendor)

View File

@@ -69,6 +69,7 @@ type source = {
s_orig_name : string; (** Original guest name (if we rename
the guest using -on, original is
still saved here). *)
s_genid : string option; (** VM Generation ID. *)
s_memory : int64; (** Memory size (bytes). *)
s_vcpu : int; (** Number of CPUs. *)
s_cpu_vendor : string option; (** Source CPU vendor. *)