[PATCH 0/4] vircommand: Make FD closing more robust on __APPLE__
by Michal Privoznik
Found these on an old branch. Might as well post them.
Michal Prívozník (4):
vircommand: Drop unused arguments from virCommandMassCloseGetFDs*()
vircommand: Isolate FD dir parsing into a separate function
vircommand: Make sysconf(_SC_OPEN_MAX) failure non-fatal
vircommand: Parse /dev/fd on *BSD-like systems when looking for opened
FDs
src/util/vircommand.c | 43 ++++++++++++++++++-------------------------
1 file changed, 18 insertions(+), 25 deletions(-)
--
2.44.2
3 months, 1 week
[PATCH v1] chardev: introduce 'reconnect-ms' and deprecate 'reconnect'
by Daniil Tatianin
The 'reconnect' option only allows to specify the time in seconds,
which is way too long for certain workflows.
We have a lightweight disk backend server, which takes about 20ms to
live update, but due to this limitation in QEMU, previously the guest
disk controller would hang for one second because it would take this
long for QEMU to reinitialize the socket connection.
Introduce a new option called 'reconnect-ms', which is the same as
'reconnect', except the value is treated as milliseconds. These are
mutually exclusive and specifying both results in an error.
'reconnect' is also deprecated by this commit to make it possible to
remove it in the future as to not keep two options that control the
same thing.
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov(a)yandex-team.ru>
Acked-by: Peter Krempa <pkrempa(a)redhat.com>
Signed-off-by: Daniil Tatianin <d-tatianin(a)yandex-team.ru>
---
Changes since v0:
- Mention the deprecation in docs (Paolo)
---
chardev/char-socket.c | 33 ++++++++++++++++++++++++---------
chardev/char.c | 3 +++
docs/about/deprecated.rst | 6 ++++++
include/chardev/char-socket.h | 2 +-
qapi/char.json | 17 +++++++++++++++--
5 files changed, 49 insertions(+), 12 deletions(-)
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 1ca9441b1b..c24331ac23 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -74,7 +74,7 @@ static void qemu_chr_socket_restart_timer(Chardev *chr)
assert(!s->reconnect_timer);
name = g_strdup_printf("chardev-socket-reconnect-%s", chr->label);
s->reconnect_timer = qemu_chr_timeout_add_ms(chr,
- s->reconnect_time * 1000,
+ s->reconnect_time_ms,
socket_reconnect_timeout,
chr);
g_source_set_name(s->reconnect_timer, name);
@@ -481,7 +481,7 @@ static void tcp_chr_disconnect_locked(Chardev *chr)
if (emit_close) {
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
- if (s->reconnect_time && !s->reconnect_timer) {
+ if (s->reconnect_time_ms && !s->reconnect_timer) {
qemu_chr_socket_restart_timer(chr);
}
}
@@ -1080,9 +1080,9 @@ static int tcp_chr_wait_connected(Chardev *chr, Error **errp)
} else {
Error *err = NULL;
if (tcp_chr_connect_client_sync(chr, &err) < 0) {
- if (s->reconnect_time) {
+ if (s->reconnect_time_ms) {
error_free(err);
- g_usleep(s->reconnect_time * 1000ULL * 1000ULL);
+ g_usleep(s->reconnect_time_ms * 1000ULL);
} else {
error_propagate(errp, err);
return -1;
@@ -1267,13 +1267,13 @@ skip_listen:
static int qmp_chardev_open_socket_client(Chardev *chr,
- int64_t reconnect,
+ int64_t reconnect_ms,
Error **errp)
{
SocketChardev *s = SOCKET_CHARDEV(chr);
- if (reconnect > 0) {
- s->reconnect_time = reconnect;
+ if (reconnect_ms > 0) {
+ s->reconnect_time_ms = reconnect_ms;
tcp_chr_connect_client_async(chr);
return 0;
} else {
@@ -1371,7 +1371,7 @@ static void qmp_chardev_open_socket(Chardev *chr,
bool is_tn3270 = sock->has_tn3270 ? sock->tn3270 : false;
bool is_waitconnect = sock->has_wait ? sock->wait : false;
bool is_websock = sock->has_websocket ? sock->websocket : false;
- int64_t reconnect = sock->has_reconnect ? sock->reconnect : 0;
+ int64_t reconnect_ms = 0;
SocketAddress *addr;
s->is_listen = is_listen;
@@ -1443,7 +1443,13 @@ static void qmp_chardev_open_socket(Chardev *chr,
return;
}
} else {
- if (qmp_chardev_open_socket_client(chr, reconnect, errp) < 0) {
+ if (sock->has_reconnect) {
+ reconnect_ms = sock->reconnect * 1000ULL;
+ } else if (sock->has_reconnect_ms) {
+ reconnect_ms = sock->reconnect_ms;
+ }
+
+ if (qmp_chardev_open_socket_client(chr, reconnect_ms, errp) < 0) {
return;
}
}
@@ -1509,6 +1515,15 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
sock->wait = qemu_opt_get_bool(opts, "wait", true);
sock->has_reconnect = qemu_opt_find(opts, "reconnect");
sock->reconnect = qemu_opt_get_number(opts, "reconnect", 0);
+ sock->has_reconnect_ms = qemu_opt_find(opts, "reconnect-ms");
+ sock->reconnect_ms = qemu_opt_get_number(opts, "reconnect-ms", 0);
+
+ if (sock->has_reconnect_ms && sock->has_reconnect) {
+ error_setg(errp,
+ "'reconnect' and 'reconnect-ms' are mutually exclusive");
+ return;
+ }
+
sock->tls_creds = g_strdup(qemu_opt_get(opts, "tls-creds"));
sock->tls_authz = g_strdup(qemu_opt_get(opts, "tls-authz"));
diff --git a/chardev/char.c b/chardev/char.c
index ba847b6e9e..35623c78a3 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -888,6 +888,9 @@ QemuOptsList qemu_chardev_opts = {
},{
.name = "reconnect",
.type = QEMU_OPT_NUMBER,
+ },{
+ .name = "reconnect-ms",
+ .type = QEMU_OPT_NUMBER,
},{
.name = "telnet",
.type = QEMU_OPT_BOOL,
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 88f0f03786..e5db9bc6e9 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -430,6 +430,12 @@ Backend ``memory`` (since 9.0)
``memory`` is a deprecated synonym for ``ringbuf``.
+``reconnect`` (since 9.2)
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The ``reconnect`` option only allows specifiying second granularity timeouts,
+which is not enough for all types of use cases, use ``reconnect-ms`` instead.
+
CPU device properties
'''''''''''''''''''''
diff --git a/include/chardev/char-socket.h b/include/chardev/char-socket.h
index 0708ca6fa9..d6d13ad37f 100644
--- a/include/chardev/char-socket.h
+++ b/include/chardev/char-socket.h
@@ -74,7 +74,7 @@ struct SocketChardev {
bool is_websock;
GSource *reconnect_timer;
- int64_t reconnect_time;
+ int64_t reconnect_time_ms;
bool connect_err_reported;
QIOTask *connect_task;
diff --git a/qapi/char.json b/qapi/char.json
index ef58445cee..7f117438c6 100644
--- a/qapi/char.json
+++ b/qapi/char.json
@@ -273,7 +273,19 @@
#
# @reconnect: For a client socket, if a socket is disconnected, then
# attempt a reconnect after the given number of seconds. Setting
-# this to zero disables this function. (default: 0) (Since: 2.2)
+# this to zero disables this function. The use of this member is
+# deprecated, use @reconnect-ms instead. (default: 0) (Since: 2.2)
+#
+# @reconnect-ms: For a client socket, if a socket is disconnected,
+# then attempt a reconnect after the given number of milliseconds.
+# Setting this to zero disables this function. This member is
+# mutually exclusive with @reconnect.
+# (default: 0) (Since: 9.2)
+#
+# Features:
+#
+# @deprecated: Member @reconnect is deprecated. Use @reconnect-ms
+# instead.
#
# Since: 1.4
##
@@ -287,7 +299,8 @@
'*telnet': 'bool',
'*tn3270': 'bool',
'*websocket': 'bool',
- '*reconnect': 'int' },
+ '*reconnect': { 'type': 'int', 'features': [ 'deprecated' ] },
+ '*reconnect-ms': 'int' },
'base': 'ChardevCommon' }
##
--
2.34.1
3 months, 1 week
[PATCH V2] libxl: Reject VM config referencing nwfilters
by Jim Fehlig
The Xen libxl driver does not support nwfilter. Introduce a
deviceValidateCallback function with a check for nwfilters, returning
VIR_ERR_CONFIG_UNSUPPORTED if any are found. Also fail to start any
existing VMs referencing nwfilters.
Drivers generally ignore unrecognized XML configuration, but ignoring
a user's request to filter VM network traffic can be viewed as a
security issue.
Signed-off-by: Jim Fehlig <jfehlig(a)suse.com>
---
This is a V2 of patch2 from this series
https://lists.libvirt.org/archives/list/devel@lists.libvirt.org/thread/QD...
I've pushed patch1. Personally I'm fine leaving it at that, but I
made it this far so might as well give patch2 another attempt :-).
There's still the open question whether the same should be done for
the other hypervisor drivers that do not support nwfilters.
Changes in V2:
Use deviceValidateCallback instead of devicesPostParseCallback
Reject use of nwfilters at VM start
src/libxl/libxl_conf.c | 7 +++++++
src/libxl/libxl_domain.c | 18 ++++++++++++++++++
2 files changed, 25 insertions(+)
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 62e1be6672..bf5d925a20 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -1279,6 +1279,13 @@ libxlMakeNic(virDomainDef *def,
* x_nics[i].mtu = 1492;
*/
+ if (l_nic->filter) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("filterref is not supported in %1$s"),
+ virDomainVirtTypeToString(def->virtType));
+ return -1;
+ }
+
if (l_nic->script && !(actual_type == VIR_DOMAIN_NET_TYPE_BRIDGE ||
actual_type == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index 0f129ec69c..d400f32627 100644
--- a/src/libxl/libxl_domain.c
+++ b/src/libxl/libxl_domain.c
@@ -356,12 +356,30 @@ libxlDomainDefValidate(const virDomainDef *def,
return 0;
}
+static int
+libxlDomainDeviceDefValidate(const virDomainDeviceDef *dev,
+ const virDomainDef *def,
+ void *opaque G_GNUC_UNUSED,
+ void *parseOpaque G_GNUC_UNUSED)
+{
+ if (dev->type == VIR_DOMAIN_DEVICE_NET && dev->data.net->filter) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("filterref is not supported in %1$s"),
+ virDomainVirtTypeToString(def->virtType));
+ return -1;
+ }
+
+ return 0;
+}
+
+
virDomainDefParserConfig libxlDomainDefParserConfig = {
.macPrefix = { 0x00, 0x16, 0x3e },
.netPrefix = LIBXL_GENERATED_PREFIX_XEN,
.devicesPostParseCallback = libxlDomainDeviceDefPostParse,
.domainPostParseCallback = libxlDomainDefPostParse,
.domainValidateCallback = libxlDomainDefValidate,
+ .deviceValidateCallback = libxlDomainDeviceDefValidate,
.features = VIR_DOMAIN_DEF_FEATURE_USER_ALIAS |
VIR_DOMAIN_DEF_FEATURE_FW_AUTOSELECT |
--
2.35.3
3 months, 1 week
[PATCH 0/2] Reject Xen VM config containing nwfilter references
by Jim Fehlig
This is essentially V2 of a small series inspired by a report on the
security list about nwfilters not working with Xen VMs. V1 was posted
to the security list, so no public reference. The libxl driver simply
does not support nwfilters, so the report is really a RFE vs a
security issue.
I'm now moving the discussion to the public devel list. I don't have
time to add nwfilter support to the libxl driver, but agree the
documentation could be improved. Given the perceived security
implications, I also think it's worth considering rejecting Xen VM
<interface> configuration containing <filterref>, even though libvirt
tends to ignore unsupported XML config.
Patch1 improves the documentation. I also considered adding a
"Limitations" section to docs/drvxen.rst, but none of the other
drivers have such section. Also, for the xen one, I wasn't sure where
to start with listing limitations :-P.
Patch2 rejects Xen VM config containg <filterref> in their <interface>
definitions.
Jim Fehlig (2):
docs: Clarify hypervisor support for nwfilter profiles
libxl: Reject VM config referencing nwfilters
docs/formatdomain.rst | 8 ++++----
src/libxl/libxl_domain.c | 7 +++++++
2 files changed, 11 insertions(+), 4 deletions(-)
--
2.35.3
3 months, 1 week
[PATCH v2] documentation: untrue statement in GetVersion() method description
by Stepan Zobal
In the end of virConnectGetVersion() description there is written: "not with a Read-Only connection"
which isn't true after I tried virConnectOpenReadOnly() with virConnectGetVersion() and it clearly shows the version correctly.
Signed-off-by: Stepan Zobal <szobal(a)redhat.com>
---
Removed another unnecessary comment about virConnectGetVersion() method.
src/libvirt-host.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/libvirt-host.c b/src/libvirt-host.c
index e67b36812e..b3a6421a7f 100644
--- a/src/libvirt-host.c
+++ b/src/libvirt-host.c
@@ -179,9 +179,7 @@ virConnectGetType(virConnectPtr conn)
* @conn: pointer to the hypervisor connection
* @hvVer: return value for the version of the running hypervisor (OUT)
*
- * Get the version level of the Hypervisor running. This may work only with
- * hypervisor call, i.e. with privileged access to the hypervisor, not
- * with a Read-Only connection.
+ * Get the version level of the Hypervisor running.
*
* Returns -1 in case of error, 0 otherwise. if the version can't be
* extracted by lack of capacities returns 0 and @hvVer is 0, otherwise
--
2.46.0
3 months, 1 week
[PATCH] documentation: untrue statement in GetVersion() method description
by Stepan Zobal
In the end of virConnectGetVersion() description there is written: "not with a Read-Only connection"
which isn't true after I tried virConnectOpenReadOnly() with virConnectGetVersion() and it clearly shows the version correctly.
Signed-off-by: Stepan Zobal <szobal(a)redhat.com>
---
src/libvirt-host.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/libvirt-host.c b/src/libvirt-host.c
index e67b36812e..5030707bbf 100644
--- a/src/libvirt-host.c
+++ b/src/libvirt-host.c
@@ -180,8 +180,7 @@ virConnectGetType(virConnectPtr conn)
* @hvVer: return value for the version of the running hypervisor (OUT)
*
* Get the version level of the Hypervisor running. This may work only with
- * hypervisor call, i.e. with privileged access to the hypervisor, not
- * with a Read-Only connection.
+ * hypervisor call, i.e. with privileged access to the hypervisor.
*
* Returns -1 in case of error, 0 otherwise. if the version can't be
* extracted by lack of capacities returns 0 and @hvVer is 0, otherwise
--
2.46.0
3 months, 1 week
[PATCH v2 0/2] Adapt to latest libxml2
by Jakub Palacky
I noticed a couple deprecation errors when trying to build libvirt
with the latest libxml2 version from the master branch. These patches
fix the deprecated fields.
Both functions used are available in the oldest libxml2 version
required by libvirt, so there is no need to bump it.
Changes in v2:
- Save return value of xmlCtxtGetLastError for later use
- Check that xmlCtxtGetLastError doesn't return NULL
Jakub Palacky (2):
util/virxml: use xmlCtxtGetLastError when applicable
vmx: use xmlBufferDetach() when applicable
src/util/virxml.c | 19 ++++++++++---------
src/vmx/vmx.c | 2 +-
2 files changed, 11 insertions(+), 10 deletions(-)
--
2.46.0
3 months, 1 week
[PATCH v2] util/virutil: Use readpassphrase when libbsd is available
by Jakub Palacky
When libbsd is available, use the preferred readpassphrase() function isntead of getpass()
as the getpass() function has been marked as obsolete and shouldnt be used
Signed-off-by: Jakub Palacky <jpalacky(a)redhat.com>
---
Changes in v2:
- Fix possible memory leak of g_new0
- Use PASS_MAX for max password length
- Set PASS_MAX to 1024 if not defined
meson.build | 6 ++++++
src/meson.build | 1 +
src/util/virutil.c | 17 +++++++++++++++++
3 files changed, 24 insertions(+)
diff --git a/meson.build b/meson.build
index 297fbfae48..699a65c7e8 100644
--- a/meson.build
+++ b/meson.build
@@ -954,6 +954,11 @@ if blkid_dep.found()
conf.set('WITH_BLKID', 1)
endif
+bsd_dep = dependency('libbsd', required: false)
+if bsd_dep.found()
+ conf.set('WITH_LIBBSD', 1)
+endif
+
capng_dep = dependency('libcap-ng', required: get_option('capng'))
if capng_dep.found()
conf.set('WITH_CAPNG', 1)
@@ -2335,6 +2340,7 @@ libs_summary = {
'dlopen': dlopen_dep.found(),
'fuse': fuse_dep.found(),
'glusterfs': glusterfs_dep.found(),
+ 'libbsd': bsd_dep.found(),
'libiscsi': libiscsi_dep.found(),
'libkvm': libkvm_dep.found(),
'libnbd': libnbd_dep.found(),
diff --git a/src/meson.build b/src/meson.build
index 8cce42c7ad..30ae34646e 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -9,6 +9,7 @@ src_dep = declare_dependency(
dependencies: [
glib_dep,
libxml_dep,
+ bsd_dep,
],
include_directories: [
libvirt_inc,
diff --git a/src/util/virutil.c b/src/util/virutil.c
index 6c89a48e51..bf6008fdfb 100644
--- a/src/util/virutil.c
+++ b/src/util/virutil.c
@@ -31,6 +31,10 @@
# include <conio.h>
#endif /* WIN32 */
+#ifdef WITH_LIBBSD
+# include <bsd/readpassphrase.h>
+#endif
+
#ifdef __linux__
# include <sys/sysmacros.h>
#endif
@@ -1773,6 +1777,19 @@ char *virGetPassword(void)
}
return g_string_free(pw, FALSE);
+#elif WITH_LIBBSD /* !WIN32 */
+# ifndef PASS_MAX
+# define PASS_MAX 1024
+# endif
+ char *pass = NULL;
+ g_autofree char *buffer = g_new0(char, PASS_MAX);
+
+ pass = readpassphrase("", buffer, PASS_MAX, 0);
+ if (pass == NULL) {
+ return NULL;
+ }
+
+ return g_steal_pointer(&buffer);
#else /* !WIN32 */
return g_strdup(getpass(""));
#endif /* ! WIN32 */
--
2.46.0
3 months, 1 week
[PATCH 0/2] Adapt to latest libxml2
by Jakub Palacky
I noticed a couple deprecation errors when trying to build libvirt
with the latest libxml2 version from the master branch. These patches
fix the deprecated fields.
Both functions used are available in the oldest libxml2 version
required by libvirt, so there is no need to bump it.
Jakub Palacky (2):
util/virxml: use xmlCtxtGetLastError when applicable
vmx: use xmlBufferDetach() when applicable
src/util/virxml.c | 16 ++++++++--------
src/vmx/vmx.c | 2 +-
2 files changed, 9 insertions(+), 9 deletions(-)
--
2.46.0
3 months, 1 week
[PATCH] vmx: Allow '*' to appear in VMX file keys
by Richard W.M. Jones
When connecting to a VMware server (eg using vpx://) we download and
try to parse the VMware metadata '*.vmx' file of a guest. In this
case a VMX file was found which contained this key:
pciPassthru*.present = "False"
The '*' character was not previously allowed in keys so this failed to
parse with the error:
VIR_ERR_CONF_SYNTAX: VIR_FROM_CONF: configuration file syntax error:
memory conf:74: expecting an assignment
Resolves: https://issues.redhat.com/browse/RHEL-58446
Thanks: Daniel Berrange
Signed-off-by: Richard W.M. Jones <rjones(a)redhat.com>
---
src/util/virconf.c | 2 +-
tests/vmx2xmldata/esx-in-the-wild-14.vmx | 109 +++++++++++++++++++++++
tests/vmx2xmldata/esx-in-the-wild-14.xml | 35 ++++++++
tests/vmx2xmltest.c | 1 +
4 files changed, 146 insertions(+), 1 deletion(-)
diff --git a/src/util/virconf.c b/src/util/virconf.c
index 66b3e0482e..c820c94037 100644
--- a/src/util/virconf.c
+++ b/src/util/virconf.c
@@ -553,7 +553,7 @@ virConfParseName(virConfParserCtxt *ctxt)
while ((ctxt->cur < ctxt->end) &&
(g_ascii_isalnum(CUR) || (CUR == '_') ||
((ctxt->conf->flags & VIR_CONF_FLAG_VMX_FORMAT) &&
- ((CUR == ':') || (CUR == '.') || (CUR == '-'))) ||
+ ((CUR == ':') || (CUR == '.') || (CUR == '-') || (CUR == '*'))) ||
((ctxt->conf->flags & VIR_CONF_FLAG_LXC_FORMAT) &&
(CUR == '.'))))
NEXT;
diff --git a/tests/vmx2xmldata/esx-in-the-wild-14.vmx b/tests/vmx2xmldata/esx-in-the-wild-14.vmx
new file mode 100644
index 0000000000..1b06352348
--- /dev/null
+++ b/tests/vmx2xmldata/esx-in-the-wild-14.vmx
@@ -0,0 +1,109 @@
+.encoding = "UTF-8"
+displayName = "wild14"
+config.version = "8"
+virtualHW.version = "19"
+nvram = "wild14.nvram"
+pciBridge0.present = "TRUE"
+svga.present = "TRUE"
+pciBridge4.present = "TRUE"
+pciBridge4.virtualDev = "pcieRootPort"
+pciBridge4.functions = "8"
+pciBridge5.present = "TRUE"
+pciBridge5.virtualDev = "pcieRootPort"
+pciBridge5.functions = "8"
+pciBridge6.present = "TRUE"
+pciBridge6.virtualDev = "pcieRootPort"
+pciBridge6.functions = "8"
+pciBridge7.present = "TRUE"
+pciBridge7.virtualDev = "pcieRootPort"
+pciBridge7.functions = "8"
+vmci0.present = "TRUE"
+hpet0.present = "TRUE"
+numvcpus = "12"
+memSize = "32768"
+vm.createDate = "1661219530463754"
+scsi0.virtualDev = "pvscsi"
+scsi0.present = "TRUE"
+annotation = "execution env sandbox automation platform"
+guestOS = "rhel7-64"
+uuid.bios = "42 1b 22 3a f2 c1 c7 c9-a3 99 34 d2 d9 fd e2 6d"
+vc.uuid = "50 1b 83 1e 75 d8 15 f8-36 fa b9 e2 25 f3 95 aa"
+migrate.hostLog = "wild14.hlog"
+disk.EnableUUID = "true"
+guestinfo.Vrm.Server.Host = "wild14.local"
+numa.autosize.cookie = "120012"
+numa.autosize.vcpu.maxPerVirtualNode = "12"
+sched.swap.derivedName = "/vmfs/volumes/64e4b8e0/wild/wild14.vswp"
+pciBridge0.pciSlotNumber = "17"
+pciBridge4.pciSlotNumber = "21"
+pciBridge5.pciSlotNumber = "22"
+pciBridge6.pciSlotNumber = "23"
+pciBridge7.pciSlotNumber = "24"
+scsi0.pciSlotNumber = "160"
+vmci0.pciSlotNumber = "32"
+scsi0.sasWWID = "50 05 05 6a f2 c1 c7 c0"
+vmci0.id = "-637672851"
+svga.vramSize = "8388608"
+monitor.phys_bits_used = "45"
+vmotion.checkpointFBSize = "8388608"
+vmotion.checkpointSVGAPrimarySize = "8388608"
+softPowerOff = "FALSE"
+svga.guestBackedPrimaryAware = "TRUE"
+tools.syncTime = "FALSE"
+guestOS.detailed.data = "architecture='X86' bitness='64' distroName='Red Hat Enterprise Linux' distroVersion='8.8' familyName='Linux' kernelVersion='4.18.0-477.21.1.el8_8.x86_64' prettyName='Red Hat Enterprise Linux 8.8 (Ootpa)'"
+tools.remindInstall = "TRUE"
+config.readOnly = "FALSE"
+guestInfo.detailed.data = "architecture='X86' bitness='64' cpeString='cpe:/o:redhat:enterprise_linux:8::baseos' distroAddlVersion='8.10 (Ootpa)' distroName='Red Hat Enterprise Linux' distroVersion='8.10' familyName='Linux' kernelVersion='4.18.0-553.8.1.el8_10.x86_64' prettyName='Red Hat Enterprise Linux 8.10 (Ootpa)'"
+log.keepOld = "10"
+tools.setInfo.sizeLimit = "1048576"
+RemoteDisplay.maxConnections = "1"
+isolation.tools.diskWiper.disable = "True"
+isolation.tools.vmxDnDVersionGet.disable = "True"
+isolation.tools.copy.disable = "true"
+isolation.device.connectable.disable = "True"
+tools.guestlib.enableHostInfo = "False"
+isolation.device.edit.disable = "True"
+isolation.tools.setGUIOptions.enable = "False"
+pciPassthru*.present = "False"
+isolation.tools.dnd.disable = "true"
+log.rotateSize = "1024000"
+isolation.tools.paste.disable = "True"
+isolation.tools.diskShrink.disable = "True"
+time.synchronize.restore = "False"
+time.synchronize.resume.disk = "False"
+time.synchronize.tools.startup = "False"
+time.synchronize.continue = "False"
+time.synchronize.shrink = "False"
+time.synchronize.tools.enable = "False"
+mks.enable3d = "False"
+time.synchronize.resume.host = "False"
+ethernet0.addressType = "static"
+ethernet0.pciSlotNumber = "192"
+ethernet0.present = "TRUE"
+ethernet0.uptCompatibility = "TRUE"
+ethernet0.virtualDev = "vmxnet3"
+floppy0.present = "FALSE"
+ide0:0.deviceType = "atapi-cdrom"
+ide0:0.present = "TRUE"
+ide0:0.startConnected = "FALSE"
+ethernet0.opaqueNetwork.id = "a2636d32-fc15-469f-b3b4-f8193fefd097"
+ethernet0.opaqueNetwork.type = "nsx.LogicalSwitch"
+ethernet0.address = "00:00:00:00:00:00"
+vmotion.svga.mobMaxSize = "8388608"
+vmotion.svga.graphicsMemoryKB = "8192"
+scsi0:0.deviceType = "scsi-hardDisk"
+scsi0:0.fileName = "wild1.vmdk"
+sched.scsi0:0.shares = "normal"
+sched.scsi0:0.throughputCap = "off"
+scsi0:0.present = "TRUE"
+scsi0:1.deviceType = "scsi-hardDisk"
+scsi0:1.fileName = "wild2.vmdk"
+sched.scsi0:1.shares = "normal"
+sched.scsi0:1.throughputCap = "off"
+scsi0:1.present = "TRUE"
+bios.bootDelay = "10000"
+scsi0:1.redo = ""
+scsi0:0.redo = ""
+ide0:0.fileName = "emptyBackingString"
+ide0:0.clientDevice = "TRUE"
+cleanShutdown = "FALSE"
diff --git a/tests/vmx2xmldata/esx-in-the-wild-14.xml b/tests/vmx2xmldata/esx-in-the-wild-14.xml
new file mode 100644
index 0000000000..dd5c2434ee
--- /dev/null
+++ b/tests/vmx2xmldata/esx-in-the-wild-14.xml
@@ -0,0 +1,35 @@
+<domain type='vmware'>
+ <name>wild14</name>
+ <uuid>421b223a-f2c1-c7c9-a399-34d2d9fde26d</uuid>
+ <description>execution env sandbox automation platform</description>
+ <memory unit='KiB'>33554432</memory>
+ <currentMemory unit='KiB'>33554432</currentMemory>
+ <vcpu placement='static'>12</vcpu>
+ <os>
+ <type arch='x86_64'>hvm</type>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <disk type='file' device='disk'>
+ <source file='[datastore] directory/wild1.vmdk'/>
+ <target dev='sda' bus='scsi'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <disk type='file' device='disk'>
+ <source file='[datastore] directory/wild2.vmdk'/>
+ <target dev='sdb' bus='scsi'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='1'/>
+ </disk>
+ <controller type='scsi' index='0' model='vmpvscsi'/>
+ <interface type='null'>
+ <mac address='00:00:00:00:00:00' type='static'/>
+ <model type='vmxnet3'/>
+ </interface>
+ <video>
+ <model type='vmvga' vram='8192' primary='yes'/>
+ </video>
+ </devices>
+</domain>
diff --git a/tests/vmx2xmltest.c b/tests/vmx2xmltest.c
index 0fb5f13f72..3ca9541000 100644
--- a/tests/vmx2xmltest.c
+++ b/tests/vmx2xmltest.c
@@ -264,6 +264,7 @@ mymain(void)
DO_TEST("esx-in-the-wild-11");
DO_TEST("esx-in-the-wild-12");
DO_TEST("esx-in-the-wild-13");
+ DO_TEST("esx-in-the-wild-14");
DO_TEST("gsx-in-the-wild-1");
DO_TEST("gsx-in-the-wild-2");
--
2.46.0
3 months, 1 week