Not a long ago I've introduced parsing of vmx.genid and
vmx.genidX properties. They map onto our <genid/> element. The
implementation was quite straightforward: the UUID which is 128
bits long is split into two equally long parts which I then put
next to each other and used virUUIDParse() to fill the UUID
buffer. However, as it turns out it is not that simple - VMX
apparently does swap some byte pairs in both Hi and Lo parts. Do
the reverse so that the UUID is true to its original value.
Mind you, this algorithm is heavily inspired by virt-v2v code:
https://github.com/libguestfs/virt-v2v/blob/981e0c6b2d2ae0093e3f31829a8d0...
Fixes: 7d661d6e20fe82e5472d5ab6dcd97ed76291f256
Reported-by: Richard W.M. Jones <rjones(a)redhat.com>
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/vmx/vmx.c | 16 ++++++++++++----
tests/vmx2xmldata/esx-in-the-wild-10.xml | 2 +-
2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index d3540acd84..f0c30e60b6 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -1347,6 +1347,9 @@ virVMXParseGenID(virConf *conf,
{
long long vmid[2] = { 0 };
g_autofree char *uuidstr = NULL;
+ size_t i;
+ /* This mapping comes from virt-v2v sources. */
+ const int uuidmap[] = {8, 10, 12, 14, 4, 6, 0, 2, 30, 28, 26, 24, 22, 20, 18, 16};
if (virVMXGetConfigLong(conf, "vm.genid", &vmid[0], 0, true) < 0 ||
virVMXGetConfigLong(conf, "vm.genidX", &vmid[1], 0, true) < 0)
@@ -1356,10 +1359,15 @@ virVMXParseGenID(virConf *conf,
return 0;
uuidstr = g_strdup_printf("%.16llx%.16llx", vmid[0], vmid[1]);
- if (virUUIDParse(uuidstr, def->genid) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Could not parse UUID from string '%s'"),
uuidstr);
- return -1;
+ /* Ideally we would just call virUUIDParse() and be done, but it's not that
+ * simple. Some bytes in genid and genidX are swapped and we need to swap
+ * them back. This matches what virt-v2v does. */
+ for (i = 0; i < G_N_ELEMENTS(uuidmap); i++) {
+ int idx = uuidmap[i];
+ int val_hi = g_ascii_xdigit_value(uuidstr[idx]);
+ int val_lo = g_ascii_xdigit_value(uuidstr[idx + 1]);
+
+ def->genid[i] = 16 * val_hi + val_lo;
}
def->genidRequested = true;
diff --git a/tests/vmx2xmldata/esx-in-the-wild-10.xml
b/tests/vmx2xmldata/esx-in-the-wild-10.xml
index 47ed637920..59cdc68bf3 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-10.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-10.xml
@@ -1,7 +1,7 @@
<domain type='vmware'>
<name>w2019biosvmware</name>
<uuid>421a6177-5aa9-abb7-5924-fc376c18a1b4</uuid>
- <genid>13c67c91-9f47-526f-b0d6-e4dd2e4bb4f9</genid>
+ <genid>9f47526f-7c91-13c6-f9b4-4b2edde4d6b0</genid>
<memory unit='KiB'>4194304</memory>
<currentMemory unit='KiB'>4194304</currentMemory>
<vcpu placement='static'>2</vcpu>
--
2.32.0