[libvirt] [PATCH v3 0/9] Enable ramfb parameter for mediated devices
by Jonathon Jongsma
This is the third version of a patch series that adds support for a boot
display for mediated vgpu devices using the 'ramfb' parameter. This version
fixes a bunch of test failures that I had inadvertently introduced in the last
series. It also splits the 4th patch up into several separate patches as
suggested by Cole to make things more readable.
Jonathon Jongsma (9):
qemu: fix domain device validation
qemu: use g_autoptr in qemuDomainDeviceDefValidate()
qemu: Set capabilities properly for tests
qemu: set domain capability for ramfb device
qemu: set domain capability for video type "none"
qemu: validate vhost-user video backend in qemu_domain.c
qemu: move validation of video accel to qemu_domain.c
qemu: use domain caps to validate video device model
qemu: add 'ramfb' attribute for mediated devices
docs/formatdomain.html.in | 8 ++
docs/schemas/domaincommon.rng | 5 ++
src/conf/domain_capabilities.c | 17 +++-
src/conf/domain_conf.c | 11 +++
src/conf/domain_conf.h | 1 +
src/qemu/qemu_capabilities.c | 3 +
src/qemu/qemu_command.c | 17 +++-
src/qemu/qemu_domain.c | 61 ++++++-------
src/qemu/qemu_process.c | 61 -------------
.../qemu_1.7.0.x86_64.xml | 1 +
.../qemu_2.12.0-virt.aarch64.xml | 1 +
.../qemu_2.12.0.ppc64.xml | 1 +
.../qemu_2.12.0.s390x.xml | 1 +
.../qemu_2.12.0.x86_64.xml | 1 +
.../qemu_2.6.0-virt.aarch64.xml | 1 +
.../qemu_2.6.0.aarch64.xml | 1 +
.../domaincapsschemadata/qemu_2.6.0.ppc64.xml | 1 +
.../qemu_2.6.0.x86_64.xml | 1 +
.../domaincapsschemadata/qemu_2.7.0.s390x.xml | 1 +
.../qemu_2.8.0-tcg.x86_64.xml | 1 +
.../domaincapsschemadata/qemu_2.8.0.s390x.xml | 1 +
.../qemu_2.8.0.x86_64.xml | 1 +
.../qemu_2.9.0-q35.x86_64.xml | 1 +
.../qemu_2.9.0-tcg.x86_64.xml | 1 +
.../qemu_2.9.0.x86_64.xml | 1 +
.../domaincapsschemadata/qemu_3.0.0.s390x.xml | 2 +
.../qemu_3.1.0.x86_64.xml | 2 +
.../domaincapsschemadata/qemu_4.0.0.s390x.xml | 1 +
.../qemu_4.0.0.x86_64.xml | 2 +
.../qemu_4.1.0.x86_64.xml | 2 +
.../qemu_4.2.0.aarch64.xml | 2 +
.../domaincapsschemadata/qemu_4.2.0.ppc64.xml | 1 +
.../qemu_4.2.0.x86_64.xml | 2 +
tests/qemuhotplugtest.c | 3 +
...tdev-mdev-display-ramfb.x86_64-latest.args | 37 ++++++++
.../hostdev-mdev-display-ramfb.xml | 33 +++++++
tests/qemuxml2argvtest.c | 2 +
tests/qemuxml2xmltest.c | 89 +++++++++++--------
tests/securityselinuxlabeltest.c | 9 ++
39 files changed, 254 insertions(+), 133 deletions(-)
create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-ramfb.x86_64-latest.args
create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-ramfb.xml
--
2.21.0
5 years
[libvirt] [PATCH v3] Add API to change qemu agent response timeout
by Jonathon Jongsma
Some layered products such as oVirt have requested a way to avoid being
blocked by guest agent commands when querying a loaded vm. For example,
many guest agent commands are polled periodically to monitor changes,
and rather than blocking the calling process, they'd prefer to simply
time out when an agent query is taking too long.
This patch adds a way for the user to specify a custom agent timeout
that is applied to all agent commands.
One special case to note here is the 'guest-sync' command. 'guest-sync'
is issued internally prior to calling any other command. (For example,
when libvirt wants to call 'guest-get-fsinfo', we first call
'guest-sync' and then call 'guest-get-fsinfo').
Previously, the 'guest-sync' command used a 5-second timeout
(VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT), whereas the actual command that
followed always blocked indefinitely
(VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK). As part of this patch, if a
custom timeout is specified that is shorter than
5 seconds, this new timeout is also used for 'guest-sync'. If there is
no custom timeout or if the custom timeout is longer than 5 seconds, we
will continue to use the 5-second timeout.
Signed-off-by: Jonathon Jongsma <jjongsma(a)redhat.com>
---
Changes in v3:
- Changed enum names per Daniel's suggestion
- incorporated Michal's review and fixup patches
- As discussed on the mailing list, this patch does not acquire any jobs, but
simply uses mutex locking for data integrity
- libvirt release versions updated
- format and parse private agentTimeout data in status xml
include/libvirt/libvirt-domain.h | 10 +++
include/libvirt/libvirt-qemu.h | 8 +--
src/driver-hypervisor.h | 6 ++
src/libvirt-domain.c | 49 +++++++++++++
src/libvirt_public.syms | 5 ++
src/qemu/qemu_agent.c | 70 ++++++++++---------
src/qemu/qemu_agent.h | 3 +
src/qemu/qemu_domain.c | 6 ++
src/qemu/qemu_domain.h | 1 +
src/qemu/qemu_driver.c | 47 +++++++++++++
src/remote/remote_driver.c | 1 +
src/remote/remote_protocol.x | 18 ++++-
src/remote_protocol-structs | 9 +++
.../blockjob-blockdev-in.xml | 1 +
.../blockjob-mirror-in.xml | 1 +
.../disk-secinfo-upgrade-out.xml | 1 +
.../migration-in-params-in.xml | 1 +
.../migration-out-nbd-out.xml | 1 +
.../migration-out-nbd-tls-out.xml | 1 +
.../migration-out-params-in.xml | 1 +
tests/qemustatusxml2xmldata/modern-in.xml | 1 +
.../qemustatusxml2xmldata/vcpus-multi-in.xml | 1 +
tools/virsh-domain.c | 52 ++++++++++++++
23 files changed, 257 insertions(+), 37 deletions(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 22277b0a84..a2f007568c 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -4916,4 +4916,14 @@ int virDomainGetGuestInfo(virDomainPtr domain,
int *nparams,
unsigned int flags);
+typedef enum {
+ VIR_DOMAIN_AGENT_RESPONSE_TIMEOUT_BLOCK = -2,
+ VIR_DOMAIN_AGENT_RESPONSE_TIMEOUT_DEFAULT = -1,
+ VIR_DOMAIN_AGENT_RESPONSE_TIMEOUT_NOWAIT = 0,
+} virDomainAgentResponseTimeoutValues;
+
+int virDomainAgentSetResponseTimeout(virDomainPtr domain,
+ int timeout,
+ unsigned int flags);
+
#endif /* LIBVIRT_DOMAIN_H */
diff --git a/include/libvirt/libvirt-qemu.h b/include/libvirt/libvirt-qemu.h
index 891617443f..0cc2872821 100644
--- a/include/libvirt/libvirt-qemu.h
+++ b/include/libvirt/libvirt-qemu.h
@@ -43,10 +43,10 @@ virDomainPtr virDomainQemuAttach(virConnectPtr domain,
unsigned int flags);
typedef enum {
- VIR_DOMAIN_QEMU_AGENT_COMMAND_MIN = -2,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK = -2,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT = -1,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_NOWAIT = 0,
+ VIR_DOMAIN_QEMU_AGENT_COMMAND_MIN = VIR_DOMAIN_AGENT_RESPONSE_TIMEOUT_BLOCK,
+ VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK = VIR_DOMAIN_AGENT_RESPONSE_TIMEOUT_BLOCK,
+ VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT = VIR_DOMAIN_AGENT_RESPONSE_TIMEOUT_DEFAULT,
+ VIR_DOMAIN_QEMU_AGENT_COMMAND_NOWAIT = VIR_DOMAIN_AGENT_RESPONSE_TIMEOUT_NOWAIT,
VIR_DOMAIN_QEMU_AGENT_COMMAND_SHUTDOWN = 60,
} virDomainQemuAgentCommandTimeoutValues;
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index 015b2cd01c..4afd8f6ec5 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -1372,6 +1372,11 @@ typedef int
int *nparams,
unsigned int flags);
+typedef int
+(*virDrvDomainAgentSetResponseTimeout)(virDomainPtr domain,
+ int timeout,
+ unsigned int flags);
+
typedef struct _virHypervisorDriver virHypervisorDriver;
typedef virHypervisorDriver *virHypervisorDriverPtr;
@@ -1632,4 +1637,5 @@ struct _virHypervisorDriver {
virDrvDomainCheckpointGetParent domainCheckpointGetParent;
virDrvDomainCheckpointDelete domainCheckpointDelete;
virDrvDomainGetGuestInfo domainGetGuestInfo;
+ virDrvDomainAgentSetResponseTimeout domainAgentSetResponseTimeout;
};
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index dcab179e6e..02622cb2ca 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -12497,3 +12497,52 @@ int virDomainGetLaunchSecurityInfo(virDomainPtr domain,
virDispatchError(domain->conn);
return -1;
}
+
+
+/**
+ * virDomainAgentSetResponseTimeout:
+ * @domain: a domain object
+ * @timeout: timeout in seconds
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Set how long to wait for a response from guest agent commands. By default,
+ * agent commands block forever waiting for a response.
+ *
+ * @timeout must be a value from virDomainAgentCommandTimeoutValues or
+ * positive:
+ *
+ * VIR_DOMAIN_AGENT_COMMAND_TIMEOUT_BLOCK(-2): meaning to block forever
+ * waiting for a result.
+ * VIR_DOMAIN_AGENT_COMMAND_TIMEOUT_DEFAULT(-1): use default timeout value.
+ * VIR_DOMAIN_AGENT_COMMAND_TIMEOUT_NOWAIT(0): does not wait.
+ * positive value: wait for @timeout seconds
+ *
+ * Returns 0 on success, -1 on failure
+ */
+int
+virDomainAgentSetResponseTimeout(virDomainPtr domain,
+ int timeout,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "timeout=%i, flags=0x%x",
+ timeout, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ if (conn->driver->domainAgentSetResponseTimeout) {
+ if (conn->driver->domainAgentSetResponseTimeout(domain, timeout, flags) < 0)
+ goto error;
+ return 0;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index f88a77892f..c92f083758 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -862,4 +862,9 @@ LIBVIRT_5.8.0 {
virConnectSetIdentity;
} LIBVIRT_5.7.0;
+LIBVIRT_5.10.0 {
+ global:
+ virDomainAgentSetResponseTimeout;
+} LIBVIRT_5.8.0;
+
# .... define new API here using predicted next version number ....
diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
index 5a50f7f3be..7905a74f90 100644
--- a/src/qemu/qemu_agent.c
+++ b/src/qemu/qemu_agent.c
@@ -30,6 +30,7 @@
#include <sys/time.h>
#include "qemu_agent.h"
+#include "qemu_domain.h"
#include "viralloc.h"
#include "virlog.h"
#include "virerror.h"
@@ -127,6 +128,7 @@ struct _qemuAgent {
* but fire up an event on qemu monitor instead.
* Take that as indication of successful completion */
qemuAgentEvent await_event;
+ int timeout;
};
static virClassPtr qemuAgentClass;
@@ -695,6 +697,7 @@ qemuAgentOpen(virDomainObjPtr vm,
if (!(mon = virObjectLockableNew(qemuAgentClass)))
return NULL;
+ mon->timeout = QEMU_DOMAIN_PRIVATE(vm)->agentTimeout;
mon->fd = -1;
if (virCondInit(&mon->notify) < 0) {
virReportSystemError(errno, "%s",
@@ -907,6 +910,12 @@ qemuAgentGuestSync(qemuAgentPtr mon)
int send_ret;
unsigned long long id;
qemuAgentMessage sync_msg;
+ int timeout = VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT;
+
+ /* if user specified a custom agent timeout that is lower than the
+ * default timeout, use the shorter timeout instead */
+ if ((mon->timeout >= 0) && (mon->timeout < timeout))
+ timeout = mon->timeout;
memset(&sync_msg, 0, sizeof(sync_msg));
/* set only on first sync */
@@ -925,8 +934,7 @@ qemuAgentGuestSync(qemuAgentPtr mon)
VIR_DEBUG("Sending guest-sync command with ID: %llu", id);
- send_ret = qemuAgentSend(mon, &sync_msg,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT);
+ send_ret = qemuAgentSend(mon, &sync_msg, timeout);
VIR_DEBUG("qemuAgentSend returned: %d", send_ret);
@@ -1301,8 +1309,7 @@ int qemuAgentFSFreeze(qemuAgentPtr mon, const char **mountpoints,
if (!cmd)
goto cleanup;
- if (qemuAgentCommand(mon, cmd, &reply, true,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0)
+ if (qemuAgentCommand(mon, cmd, &reply, true, mon->timeout) < 0)
goto cleanup;
if (virJSONValueObjectGetNumberInt(reply, "return", &ret) < 0) {
@@ -1339,8 +1346,7 @@ int qemuAgentFSThaw(qemuAgentPtr mon)
if (!cmd)
return -1;
- if (qemuAgentCommand(mon, cmd, &reply, true,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0)
+ if (qemuAgentCommand(mon, cmd, &reply, true, mon->timeout) < 0)
goto cleanup;
if (virJSONValueObjectGetNumberInt(reply, "return", &ret) < 0) {
@@ -1377,8 +1383,7 @@ qemuAgentSuspend(qemuAgentPtr mon,
return -1;
mon->await_event = QEMU_AGENT_EVENT_SUSPEND;
- ret = qemuAgentCommand(mon, cmd, &reply, false,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK);
+ ret = qemuAgentCommand(mon, cmd, &reply, false, mon->timeout);
virJSONValueFree(cmd);
virJSONValueFree(reply);
@@ -1434,8 +1439,7 @@ qemuAgentFSTrim(qemuAgentPtr mon,
if (!cmd)
return ret;
- ret = qemuAgentCommand(mon, cmd, &reply, false,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK);
+ ret = qemuAgentCommand(mon, cmd, &reply, false, mon->timeout);
virJSONValueFree(cmd);
virJSONValueFree(reply);
@@ -1456,8 +1460,7 @@ qemuAgentGetVCPUs(qemuAgentPtr mon,
if (!(cmd = qemuAgentMakeCommand("guest-get-vcpus", NULL)))
return -1;
- if (qemuAgentCommand(mon, cmd, &reply, true,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0)
+ if (qemuAgentCommand(mon, cmd, &reply, true, mon->timeout) < 0)
goto cleanup;
if (!(data = virJSONValueObjectGetArray(reply, "return"))) {
@@ -1572,8 +1575,7 @@ qemuAgentSetVCPUsCommand(qemuAgentPtr mon,
NULL)))
goto cleanup;
- if (qemuAgentCommand(mon, cmd, &reply, true,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0)
+ if (qemuAgentCommand(mon, cmd, &reply, true, mon->timeout) < 0)
goto cleanup;
/* All negative values are invalid. Return of 0 is bogus since we wouldn't
@@ -1728,8 +1730,7 @@ qemuAgentGetHostname(qemuAgentPtr mon,
if (!cmd)
return ret;
- if (qemuAgentCommand(mon, cmd, &reply, true,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0) {
+ if (qemuAgentCommand(mon, cmd, &reply, true, mon->timeout) < 0) {
if (qemuAgentErrorCommandUnsupported(reply))
ret = -2;
goto cleanup;
@@ -1773,8 +1774,7 @@ qemuAgentGetTime(qemuAgentPtr mon,
if (!cmd)
return ret;
- if (qemuAgentCommand(mon, cmd, &reply, true,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0)
+ if (qemuAgentCommand(mon, cmd, &reply, true, mon->timeout) < 0)
goto cleanup;
if (virJSONValueObjectGetNumberUlong(reply, "return", &json_time) < 0) {
@@ -1839,8 +1839,7 @@ qemuAgentSetTime(qemuAgentPtr mon,
if (!cmd)
return ret;
- if (qemuAgentCommand(mon, cmd, &reply, true,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0)
+ if (qemuAgentCommand(mon, cmd, &reply, true, mon->timeout) < 0)
goto cleanup;
ret = 0;
@@ -2043,8 +2042,7 @@ qemuAgentGetFSInfoInternal(qemuAgentPtr mon,
if (!cmd)
return ret;
- if (qemuAgentCommand(mon, cmd, &reply, true,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0) {
+ if (qemuAgentCommand(mon, cmd, &reply, true, mon->timeout) < 0) {
if (qemuAgentErrorCommandUnsupported(reply))
ret = -2;
goto cleanup;
@@ -2333,8 +2331,7 @@ qemuAgentGetInterfaces(qemuAgentPtr mon,
if (!(cmd = qemuAgentMakeCommand("guest-network-get-interfaces", NULL)))
goto cleanup;
- if (qemuAgentCommand(mon, cmd, &reply, true,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0)
+ if (qemuAgentCommand(mon, cmd, &reply, true, mon->timeout) < 0)
goto cleanup;
if (!(ret_array = virJSONValueObjectGet(reply, "return"))) {
@@ -2511,8 +2508,7 @@ qemuAgentSetUserPassword(qemuAgentPtr mon,
NULL)))
goto cleanup;
- if (qemuAgentCommand(mon, cmd, &reply, true,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0)
+ if (qemuAgentCommand(mon, cmd, &reply, true, mon->timeout) < 0)
goto cleanup;
ret = 0;
@@ -2543,8 +2539,7 @@ qemuAgentGetUsers(qemuAgentPtr mon,
if (!(cmd = qemuAgentMakeCommand("guest-get-users", NULL)))
return -1;
- if (qemuAgentCommand(mon, cmd, &reply, true,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0) {
+ if (qemuAgentCommand(mon, cmd, &reply, true, mon->timeout) < 0) {
if (qemuAgentErrorCommandUnsupported(reply))
return -2;
return -1;
@@ -2633,8 +2628,7 @@ qemuAgentGetOSInfo(qemuAgentPtr mon,
if (!(cmd = qemuAgentMakeCommand("guest-get-osinfo", NULL)))
return -1;
- if (qemuAgentCommand(mon, cmd, &reply, true,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0) {
+ if (qemuAgentCommand(mon, cmd, &reply, true, mon->timeout) < 0) {
if (qemuAgentErrorCommandUnsupported(reply))
return -2;
return -1;
@@ -2689,8 +2683,7 @@ qemuAgentGetTimezone(qemuAgentPtr mon,
if (!(cmd = qemuAgentMakeCommand("guest-get-timezone", NULL)))
return -1;
- if (qemuAgentCommand(mon, cmd, &reply, true,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0) {
+ if (qemuAgentCommand(mon, cmd, &reply, true, mon->timeout) < 0) {
if (qemuAgentErrorCommandUnsupported(reply))
return -2;
return -1;
@@ -2719,3 +2712,16 @@ qemuAgentGetTimezone(qemuAgentPtr mon,
return 0;
}
+
+/* qemuAgentSetResponseTimeout:
+ * mon: agent monitor
+ * timeout: number of seconds to wait for agent response
+ *
+ * The agent object must be locked prior to calling this function.
+ */
+void
+qemuAgentSetResponseTimeout(qemuAgentPtr mon,
+ int timeout)
+{
+ mon->timeout = timeout;
+}
diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h
index 78e648992a..85e436cf68 100644
--- a/src/qemu/qemu_agent.h
+++ b/src/qemu/qemu_agent.h
@@ -140,3 +140,6 @@ int qemuAgentGetTimezone(qemuAgentPtr mon,
virTypedParameterPtr *params,
int *nparams,
int *maxparams);
+
+void qemuAgentSetResponseTimeout(qemuAgentPtr mon,
+ int timeout);
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 54dde34f15..86358341d5 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2093,6 +2093,8 @@ qemuDomainObjPrivateAlloc(void *opaque)
if (!(priv->dbusVMStates = virHashCreate(5, dbusVMStateHashFree)))
goto error;
+ /* agent commands block by default, user can choose different behavior */
+ priv->agentTimeout = VIR_DOMAIN_AGENT_RESPONSE_TIMEOUT_BLOCK;
priv->migMaxBandwidth = QEMU_DOMAIN_MIG_BANDWIDTH_MAX;
priv->driver = opaque;
@@ -2875,6 +2877,8 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf,
if (qemuDomainObjPrivateXMLFormatSlirp(buf, vm) < 0)
return -1;
+ virBufferAsprintf(buf, "<agentTimeout>%i</agentTimeout>\n", priv->agentTimeout);
+
return 0;
}
@@ -3672,6 +3676,8 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt,
priv->memPrealloc = virXPathBoolean("boolean(./memPrealloc)", ctxt) == 1;
+ virXPathInt("string(./agentTimeout)", ctxt, &priv->agentTimeout);
+
return 0;
error:
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index ab00b25789..98a9540275 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -293,6 +293,7 @@ struct _qemuDomainObjPrivate {
virDomainChrSourceDefPtr monConfig;
bool monError;
unsigned long long monStart;
+ int agentTimeout;
qemuAgentPtr agent;
bool agentError;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c969a3d463..77a26ccf2e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -22666,6 +22666,52 @@ qemuDomainGetGuestInfo(virDomainPtr dom,
return ret;
}
+
+static int
+qemuDomainAgentSetResponseTimeout(virDomainPtr dom,
+ int timeout,
+ unsigned int flags)
+{
+ virDomainObjPtr vm = NULL;
+ int ret = -1;
+
+ virCheckFlags(0, -1);
+
+ if (timeout < VIR_DOMAIN_QEMU_AGENT_COMMAND_MIN) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("guest agent timeout '%d' is "
+ "less than the minimum '%d'"),
+ timeout, VIR_DOMAIN_QEMU_AGENT_COMMAND_MIN);
+ return -1;
+ }
+
+ if (!(vm = qemuDomainObjFromDomain(dom)))
+ return -1;
+
+ if (virDomainAgentSetResponseTimeoutEnsureACL(dom->conn, vm->def) < 0)
+ goto cleanup;
+
+ /* If domain has an agent, change its timeout. Otherwise just save the
+ * request so that we can set the timeout when the agent appears */
+ if (qemuDomainAgentAvailable(vm, false)) {
+ /* We don't need to acquire a job since we're not interacting with the
+ * agent or the qemu monitor. We're only setting a struct member, so
+ * just acquire the mutex lock. Worst case, any in-process agent
+ * commands will use the newly-set agent timeout. */
+ virObjectLock(QEMU_DOMAIN_PRIVATE(vm)->agent);
+ qemuAgentSetResponseTimeout(QEMU_DOMAIN_PRIVATE(vm)->agent, timeout);
+ virObjectUnlock(QEMU_DOMAIN_PRIVATE(vm)->agent);
+ }
+
+ QEMU_DOMAIN_PRIVATE(vm)->agentTimeout = timeout;
+ ret = 0;
+
+ cleanup:
+ virDomainObjEndAPI(&vm);
+ return ret;
+}
+
+
static virHypervisorDriver qemuHypervisorDriver = {
.name = QEMU_DRIVER_NAME,
.connectURIProbe = qemuConnectURIProbe,
@@ -22902,6 +22948,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
.domainCheckpointGetParent = qemuDomainCheckpointGetParent, /* 5.6.0 */
.domainCheckpointDelete = qemuDomainCheckpointDelete, /* 5.6.0 */
.domainGetGuestInfo = qemuDomainGetGuestInfo, /* 5.7.0 */
+ .domainAgentSetResponseTimeout = qemuDomainAgentSetResponseTimeout, /* 5.10.0 */
};
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 503f49a902..a1384fc655 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -8701,6 +8701,7 @@ static virHypervisorDriver hypervisor_driver = {
.domainCheckpointGetParent = remoteDomainCheckpointGetParent, /* 5.6.0 */
.domainCheckpointDelete = remoteDomainCheckpointDelete, /* 5.6.0 */
.domainGetGuestInfo = remoteDomainGetGuestInfo, /* 5.7.0 */
+ .domainAgentSetResponseTimeout = remoteDomainAgentSetResponseTimeout, /* 5.10.0 */
};
static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index f4e3392212..23e42d17b1 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -3744,6 +3744,16 @@ struct remote_connect_set_identity_args {
unsigned int flags;
};
+struct remote_domain_agent_set_response_timeout_args {
+ remote_nonnull_domain dom;
+ int timeout;
+ unsigned int flags;
+};
+
+struct remote_domain_agent_set_response_timeout_ret {
+ int result;
+};
+
/*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */
@@ -6617,5 +6627,11 @@ enum remote_procedure {
* @generate: client
* @acl: connect:write
*/
- REMOTE_PROC_CONNECT_SET_IDENTITY = 419
+ REMOTE_PROC_CONNECT_SET_IDENTITY = 419,
+
+ /**
+ * @generate: both
+ * @acl: domain:write
+ */
+ REMOTE_PROC_DOMAIN_AGENT_SET_RESPONSE_TIMEOUT = 420
};
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 51606e7473..9ad7a857e0 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -3114,6 +3114,14 @@ struct remote_connect_set_identity_args {
} params;
u_int flags;
};
+struct remote_domain_agent_set_response_timeout_args {
+ remote_nonnull_domain dom;
+ int timeout;
+ u_int flags;
+};
+struct remote_domain_agent_set_response_timeout_ret {
+ int result;
+};
enum remote_procedure {
REMOTE_PROC_CONNECT_OPEN = 1,
REMOTE_PROC_CONNECT_CLOSE = 2,
@@ -3534,4 +3542,5 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_CHECKPOINT_DELETE = 417,
REMOTE_PROC_DOMAIN_GET_GUEST_INFO = 418,
REMOTE_PROC_CONNECT_SET_IDENTITY = 419,
+ REMOTE_PROC_DOMAIN_AGENT_SET_RESPONSE_TIMEOUT = 420,
};
diff --git a/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml b/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml
index e9031b7087..4f6930001e 100644
--- a/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml
+++ b/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml
@@ -338,6 +338,7 @@
</chains>
</blockjob>
</blockjobs>
+ <agentTimeout>-2</agentTimeout>
<domain type='kvm' id='4'>
<name>copy</name>
<uuid>0439a4a8-db56-4933-9183-d8681d7b0746</uuid>
diff --git a/tests/qemustatusxml2xmldata/blockjob-mirror-in.xml b/tests/qemustatusxml2xmldata/blockjob-mirror-in.xml
index 0fba3b69e7..abd9f62965 100644
--- a/tests/qemustatusxml2xmldata/blockjob-mirror-in.xml
+++ b/tests/qemustatusxml2xmldata/blockjob-mirror-in.xml
@@ -23,6 +23,7 @@
<channelTargetDir path='/tmp/channel'/>
<allowReboot value='yes'/>
<blockjobs active='yes'/>
+ <agentTimeout>-2</agentTimeout>
<domain type='qemu' id='1'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
diff --git a/tests/qemustatusxml2xmldata/disk-secinfo-upgrade-out.xml b/tests/qemustatusxml2xmldata/disk-secinfo-upgrade-out.xml
index 3d5e8f1438..5d3287606f 100644
--- a/tests/qemustatusxml2xmldata/disk-secinfo-upgrade-out.xml
+++ b/tests/qemustatusxml2xmldata/disk-secinfo-upgrade-out.xml
@@ -258,6 +258,7 @@
<chardevStdioLogd/>
<allowReboot value='yes'/>
<blockjobs active='no'/>
+ <agentTimeout>-2</agentTimeout>
<domain type='kvm' id='1'>
<name>upstream</name>
<uuid>dcf47dbd-46d1-4d5b-b442-262a806a333a</uuid>
diff --git a/tests/qemustatusxml2xmldata/migration-in-params-in.xml b/tests/qemustatusxml2xmldata/migration-in-params-in.xml
index 80cc4b4666..fdc2d39173 100644
--- a/tests/qemustatusxml2xmldata/migration-in-params-in.xml
+++ b/tests/qemustatusxml2xmldata/migration-in-params-in.xml
@@ -257,6 +257,7 @@
<chardevStdioLogd/>
<allowReboot value='yes'/>
<blockjobs active='no'/>
+ <agentTimeout>-2</agentTimeout>
<domain type='kvm' id='1'>
<name>nest</name>
<uuid>994cee0d-2a70-4937-9693-0431e39d20f7</uuid>
diff --git a/tests/qemustatusxml2xmldata/migration-out-nbd-out.xml b/tests/qemustatusxml2xmldata/migration-out-nbd-out.xml
index 455c30be85..304fb1b77f 100644
--- a/tests/qemustatusxml2xmldata/migration-out-nbd-out.xml
+++ b/tests/qemustatusxml2xmldata/migration-out-nbd-out.xml
@@ -260,6 +260,7 @@
<chardevStdioLogd/>
<allowReboot value='yes'/>
<blockjobs active='no'/>
+ <agentTimeout>-2</agentTimeout>
<domain type='kvm' id='4'>
<name>upstream</name>
<uuid>dcf47dbd-46d1-4d5b-b442-262a806a333a</uuid>
diff --git a/tests/qemustatusxml2xmldata/migration-out-nbd-tls-out.xml b/tests/qemustatusxml2xmldata/migration-out-nbd-tls-out.xml
index 409e97a918..d69796e029 100644
--- a/tests/qemustatusxml2xmldata/migration-out-nbd-tls-out.xml
+++ b/tests/qemustatusxml2xmldata/migration-out-nbd-tls-out.xml
@@ -289,6 +289,7 @@
<chardevStdioLogd/>
<allowReboot value='yes'/>
<blockjobs active='no'/>
+ <agentTimeout>-2</agentTimeout>
<domain type='kvm' id='3'>
<name>upstream</name>
<uuid>dcf47dbd-46d1-4d5b-b442-262a806a333a</uuid>
diff --git a/tests/qemustatusxml2xmldata/migration-out-params-in.xml b/tests/qemustatusxml2xmldata/migration-out-params-in.xml
index 4a660281d2..1956eac120 100644
--- a/tests/qemustatusxml2xmldata/migration-out-params-in.xml
+++ b/tests/qemustatusxml2xmldata/migration-out-params-in.xml
@@ -271,6 +271,7 @@
<chardevStdioLogd/>
<allowReboot value='yes'/>
<blockjobs active='no'/>
+ <agentTimeout>-2</agentTimeout>
<domain type='kvm' id='7'>
<name>nest</name>
<uuid>994cee0d-2a70-4937-9693-0431e39d20f7</uuid>
diff --git a/tests/qemustatusxml2xmldata/modern-in.xml b/tests/qemustatusxml2xmldata/modern-in.xml
index 2125b899f4..8a2718293f 100644
--- a/tests/qemustatusxml2xmldata/modern-in.xml
+++ b/tests/qemustatusxml2xmldata/modern-in.xml
@@ -261,6 +261,7 @@
<allowReboot value='yes'/>
<nodename index='123'/>
<blockjobs active='no'/>
+ <agentTimeout>-2</agentTimeout>
<domain type='kvm' id='1'>
<name>upstream</name>
<uuid>dcf47dbd-46d1-4d5b-b442-262a806a333a</uuid>
diff --git a/tests/qemustatusxml2xmldata/vcpus-multi-in.xml b/tests/qemustatusxml2xmldata/vcpus-multi-in.xml
index b8ec650714..11ec74ecf8 100644
--- a/tests/qemustatusxml2xmldata/vcpus-multi-in.xml
+++ b/tests/qemustatusxml2xmldata/vcpus-multi-in.xml
@@ -309,6 +309,7 @@
<channelTargetDir path='/tmp/channel'/>
<allowReboot value='yes'/>
<blockjobs active='no'/>
+ <agentTimeout>-2</agentTimeout>
<domain type='kvm'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 0feb21ef17..def4107d27 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -9832,6 +9832,52 @@ cmdQemuAgentCommand(vshControl *ctl, const vshCmd *cmd)
return ret;
}
+/*
+ * "guest-agent-timeout" command
+ */
+static const vshCmdInfo info_guest_agent_timeout[] = {
+ {.name = "help",
+ .data = N_("Set the guest agent timeout")
+ },
+ {.name = "desc",
+ .data = N_("Set the number of seconds to wait for a response from the guest agent.")
+ },
+ {.name = NULL}
+};
+
+static const vshCmdOptDef opts_guest_agent_timeout[] = {
+ VIRSH_COMMON_OPT_DOMAIN_FULL(0),
+ {.name = "timeout",
+ .type = VSH_OT_INT,
+ .flags = VSH_OFLAG_REQ_OPT,
+ .help = N_("timeout seconds.")
+ },
+ {.name = NULL}
+};
+
+static bool
+cmdGuestAgentTimeout(vshControl *ctl, const vshCmd *cmd)
+{
+ virDomainPtr dom = NULL;
+ int timeout;
+ const unsigned int flags = 0;
+ bool ret = false;
+
+ dom = virshCommandOptDomain(ctl, cmd, NULL);
+ if (dom == NULL)
+ goto cleanup;
+
+ if (vshCommandOptInt(ctl, cmd, "timeout", &timeout) < 0)
+ goto cleanup;
+
+ if (virDomainAgentSetResponseTimeout(dom, timeout, flags) < 0)
+ goto cleanup;
+
+ ret = true;
+ cleanup:
+ virshDomainFree(dom);
+ return ret;
+}
/*
* "lxc-enter-namespace" namespace
@@ -14492,6 +14538,12 @@ const vshCmdDef domManagementCmds[] = {
.info = info_qemu_agent_command,
.flags = 0
},
+ {.name = "guest-agent-timeout",
+ .handler = cmdGuestAgentTimeout,
+ .opts = opts_guest_agent_timeout,
+ .info = info_guest_agent_timeout,
+ .flags = 0
+ },
{.name = "reboot",
.handler = cmdReboot,
.opts = opts_reboot,
--
2.21.0
5 years
[libvirt] [PATCH 0/3] Prefer g_mkstemp_full and g_mkdtemp (glib chronicles)
by Ján Tomko
Remove the dependency on three more gnulib modules:
mkdtemp
mkostemp
mkostemps
Note: this series is not affiliated with the kill-a-gnulib-module-a-day initiative
Ján Tomko (3):
Use g_mkstemp_full instead of mkostemp(s)
Use g_mkdtemp instead of mkdtemp
syntax-check: prefer g_mkstemp_full and g_mkdtemp
build-aux/syntax-check.mk | 13 ++++++++++---
src/qemu/qemu_driver.c | 8 ++++----
src/qemu/qemu_process.c | 2 +-
src/storage/storage_driver.c | 2 +-
src/storage/storage_util.c | 2 +-
src/util/virlog.c | 8 +-------
src/vbox/vbox_common.c | 4 ++--
tests/fdstreamtest.c | 2 +-
tests/qemuhotplugtest.c | 2 +-
tests/qemumemlocktest.c | 2 +-
tests/qemumonitortestutils.c | 2 +-
tests/qemuxml2argvtest.c | 2 +-
tests/qemuxml2xmltest.c | 2 +-
tests/scsihosttest.c | 2 +-
tests/testutilsqemu.c | 4 ++--
tests/vircgrouptest.c | 2 +-
tests/virfiletest.c | 2 +-
tests/virhostdevtest.c | 2 +-
tests/virnetsockettest.c | 4 ++--
tests/virpcitest.c | 2 +-
tests/virscsitest.c | 2 +-
tools/vsh.c | 4 ++--
22 files changed, 38 insertions(+), 37 deletions(-)
--
2.21.0
5 years
[libvirt] [PATCH v2 0/4] replace snprintf by g_snprintf (kill-a-gnulib-module-a-day initiative)
by Pavel Hrdina
Pavel Hrdina (4):
replace use of gnulib snprintf by g_snprintf
bootstrap.conf: remove usage of snprintf gnulib module
syntax-check: update of sprintf rule to mention g_snpritnf
syntax-check: forbid usage of snprintf
bootstrap.conf | 1 -
build-aux/syntax-check.mk | 12 +++++-
src/hyperv/hyperv_driver.c | 4 +-
src/libxl/libxl_conf.c | 22 +++++------
src/libxl/libxl_migration.c | 4 +-
src/lxc/lxc_process.c | 6 +--
src/nwfilter/nwfilter_ebiptables_driver.c | 36 +++++++++---------
src/nwfilter/nwfilter_learnipaddr.c | 2 +-
src/openvz/openvz_driver.c | 6 +--
src/qemu/qemu_agent.c | 46 +++++++++++------------
src/qemu/qemu_driver.c | 8 ++--
src/security/security_dac.c | 8 ++--
src/security/virt-aa-helper.c | 2 +-
src/storage/storage_util.c | 2 +-
src/util/virhostcpu.c | 2 +-
src/util/viriptables.c | 6 +--
src/util/virmacaddr.c | 8 ++--
src/util/virnetdevbridge.c | 4 +-
src/util/virnetdevmacvlan.c | 12 +++---
src/util/virpci.c | 4 +-
src/util/virpidfile.c | 4 +-
src/util/virtime.c | 10 ++---
src/util/virusb.c | 8 ++--
src/util/viruuid.c | 12 +++---
src/vbox/vbox_common.c | 24 ++++++------
src/vbox/vbox_tmpl.c | 2 +-
src/vmx/vmx.c | 18 ++++-----
src/vz/vz_driver.c | 22 +++++------
src/vz/vz_sdk.c | 8 ++--
tests/libxlmock.c | 2 +-
tests/qemuagenttest.c | 12 +++---
tests/testutils.c | 2 +-
tests/virnetsockettest.c | 2 +-
tests/virpcimock.c | 28 +++++++-------
tests/virsystemdtest.c | 4 +-
tools/virsh-domain-monitor.c | 2 +-
tools/virsh-domain.c | 2 +-
tools/virt-host-validate-common.c | 2 +-
tools/vsh-table.c | 6 +--
tools/vsh.c | 22 +++++------
tools/wireshark/src/packet-libvirt.c | 2 +-
41 files changed, 198 insertions(+), 191 deletions(-)
--
2.23.0
5 years
[libvirt] [PATCH 00/12] Use GRegex instead of regcomp (glib chronicles)
by Ján Tomko
This removes the need to use gnulib's regex module.
Ján Tomko (12):
libxl: do not use G_REGEX_EXTENDED
remove unused regex.h includes
libxl: use GRegex in libxlGetAutoballoonConf
libxl: use g_autofree in xenParseSxprVifRate
libxl: use GRegex in xenParseSxprVifRate
libxl: remove 'ret' from xenParseSxprVifRate
storage: use GRegex virStorageBackendLogicalParseVolExtents
util: use GRegex in virCommandRunRegex
util: use GRegex for virLogRegex
util: use GRegex in virStringSearch
util: use GRegex in virStringMatch
tests: use GRegex in vboxsnapshotxmltest
src/libxl/libxl_capabilities.c | 2 +-
src/libxl/libxl_conf.c | 20 ++++------
src/libxl/libxl_driver.c | 1 -
src/libxl/xen_common.c | 33 ++++++-----------
src/storage/storage_backend_logical.c | 49 +++++++------------------
src/storage/storage_util.c | 1 -
src/util/vircommand.c | 37 +++++++------------
src/util/viriscsi.c | 2 -
src/util/virlog.c | 15 +++-----
src/util/virnetdevtap.c | 1 -
src/util/virstring.c | 53 +++++++++++----------------
tests/testutils.c | 1 -
tests/vboxsnapshotxmltest.c | 20 ++++------
13 files changed, 80 insertions(+), 155 deletions(-)
--
2.21.0
5 years
[libvirt] [tck PATCH 0/3] A couple of fixes for daemon hooks tests assuming system V only
by Erik Skultety
Erik Skultety (3):
hooks: Add systemd detection
hooks: Refresh the service status after performing an action
hooks: Use internal variable holding the state of the libvirtd service
lib/Sys/Virt/TCK/Hooks.pm | 26 +++++++++++++++++++++++---
scripts/hooks/051-daemon-hook.t | 8 ++++----
2 files changed, 27 insertions(+), 7 deletions(-)
--
2.23.0
5 years
[libvirt] [PATCH v3 0/6] Fix virConnectRegisterCloseCallback and get rid of global variables
by Marc Hartmayer
After discussions with Peter and Pavel at the KVM forum, I am now
sending a v3 of this series after more than a year... sorry for that
long delay!
The second patch of this patch series fixes the behavior of
virConnectRegisterCloseCallback.
The subsequent patches remove the need to have the global variables
'qemuProgram' and 'remoteProgram' in libvirtd.[ch]. They only work in
combination with the fixed behavior of
virConnectRegisterCloseCallback.
Changelog:
+ v2->v3:
- Rebased to current master
- Added Johns r-b to the first patch, all other r-b's I have
dropped as there were to many changes in the meantime
- Removed accepted patches
- Dropped patches 8 and 9
+ v1->v2:
- Removed accepted patches
- Removed NACKed patches
- Added r-b to patch 5
- Worked in comments
- Rebased
- Added patches 7-9
Marc Hartmayer (6):
rpc: use the return value of virObjectRef directly
virConnectRegisterCloseCallback: Cleanup 'opaque' if there is no
connectRegisterCloseCallback
remote: Save reference to program in daemonClientEventCallback
remote: Use domainClientEventCallbacks for
remoteReplayConnectionClosedEvent
rpc: Introduce virNetServerGetProgramLocked helper function
remote/rpc: Use virNetServerGetProgram() to determine the program
src/libvirt-host.c | 12 +-
src/libvirt_remote.syms | 1 +
src/remote/remote_daemon.c | 4 +-
src/remote/remote_daemon.h | 2 -
src/remote/remote_daemon_dispatch.c | 227 +++++++++++++++++++---------
src/rpc/gendispatch.pl | 6 +
src/rpc/virnetserver.c | 53 +++++--
src/rpc/virnetserver.h | 2 +
8 files changed, 217 insertions(+), 90 deletions(-)
--
2.21.0
5 years
[libvirt] [PATCH] virhostuptime: Wrap virHostGetBootTimeProcfs() call in an ifdef
by Michal Privoznik
The virHostGetBootTimeProcfs() function is defined only for Linux
and therefore it's only call should also be done if we're on
Linux.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
Pushed under trivial rule.
src/util/virhostuptime.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/util/virhostuptime.c b/src/util/virhostuptime.c
index 056b5c591a..8c49c3d40e 100644
--- a/src/util/virhostuptime.c
+++ b/src/util/virhostuptime.c
@@ -99,8 +99,10 @@ virHostGetBootTimeOnceInit(void)
endutxent();
# endif /* HAVE_GETUTXID */
+# ifdef __linux__
if (bootTimeErrno != 0 || bootTime == 0)
bootTimeErrno = -virHostGetBootTimeProcfs(&bootTime);
+# endif /* __linux__ */
}
#else /* !defined(HAVE_GETUTXID) && !defined(__linux__) */
--
2.23.0
5 years
[libvirt] [PATCH] qemu: Warn verbosely if using old loader:nvram pairs
by Michal Privoznik
There are two ways for specifying loader:nvram pairs:
1) --with-loader-nvram configure option
2) nvram variable in qemu.conf
Since we have FW descriptors, using this old style is
discouraged, but not as strong as one would expect. Produce more
warnings:
1) produce a warning if somebody tries the configure option
2) produce a warning if somebody sets nvram variable and at
least on FW descriptor was found
The reason for producing warning in case 1) is that package
maintainers, who set the configure option in the first place
should start moving towards FW descriptors and abandon the
configure option. After all, the warning is printed into config
output only in this case.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1763477
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
m4/virt-loader-nvram.m4 | 10 +++++++++-
src/qemu/qemu.conf | 3 +++
src/qemu/qemu_conf.c | 19 +++++++++++++++++--
3 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/m4/virt-loader-nvram.m4 b/m4/virt-loader-nvram.m4
index d7e0c8ca18..ed2ae0cf27 100644
--- a/m4/virt-loader-nvram.m4
+++ b/m4/virt-loader-nvram.m4
@@ -30,6 +30,8 @@ AC_DEFUN([LIBVIRT_CHECK_LOADER_NVRAM], [
l=$(echo $with_loader_nvram | tr ':' '\n' | wc -l)
if test $(expr $l % 2) -ne 0 ; then
AC_MSG_ERROR([Malformed --with-loader-nvram argument])
+ elif test $l -gt 0 ; then
+ AC_MSG_WARN([Note that --with-loader-nvram is obsolete and will be removed soon])
fi
AC_DEFINE_UNQUOTED([DEFAULT_LOADER_NVRAM], ["$with_loader_nvram"],
[List of loader:nvram pairs])
@@ -37,5 +39,11 @@ AC_DEFUN([LIBVIRT_CHECK_LOADER_NVRAM], [
])
AC_DEFUN([LIBVIRT_RESULT_LOADER_NVRAM], [
- LIBVIRT_RESULT([Loader/NVRAM], [$with_loader_nvram])
+ if test "x$with_loader_nvram" != "xno" && \
+ test "x$with_loader_nvram" != "x" ; then
+ LIBVIRT_RESULT([Loader/NVRAM], [$with_loader_nvram],
+ [!!! Using this configure option is strongly discouraged !!!])
+ else
+ LIBVIRT_RESULT([Loader/NVRAM], [$with_loader_nvram])
+ fi
])
diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index b3a3428e4c..7a056b037e 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -761,6 +761,9 @@
# source tree. These metadata files are distributed alongside any
# firmware images intended for use with QEMU.
#
+# NOTE: if ANY firmware metadata files are detected, this setting
+# will be COMPLETELY IGNORED.
+#
# ------------------------------------------
#
# When a domain is configured to use UEFI instead of standard
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index fae697a2ef..293f2635cc 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -32,6 +32,7 @@
#include "qemu_conf.h"
#include "qemu_capabilities.h"
#include "qemu_domain.h"
+#include "qemu_firmware.h"
#include "qemu_security.h"
#include "viruuid.h"
#include "virbuffer.h"
@@ -799,7 +800,8 @@ virQEMUDriverConfigLoadLogEntry(virQEMUDriverConfigPtr cfg,
static int
virQEMUDriverConfigLoadNVRAMEntry(virQEMUDriverConfigPtr cfg,
- virConfPtr conf)
+ virConfPtr conf,
+ bool privileged)
{
VIR_AUTOSTRINGLIST nvram = NULL;
size_t i;
@@ -807,8 +809,21 @@ virQEMUDriverConfigLoadNVRAMEntry(virQEMUDriverConfigPtr cfg,
if (virConfGetValueStringList(conf, "nvram", false, &nvram) < 0)
return -1;
if (nvram) {
+ VIR_AUTOSTRINGLIST fwList = NULL;
+
virFirmwareFreeList(cfg->firmwares, cfg->nfirmwares);
+ if (qemuFirmwareFetchConfigs(&fwList, privileged) < 0)
+ return -1;
+
+ if (fwList) {
+ VIR_WARN("Obsolete nvram variable is set while firmware metadata "
+ "files found. Note that the nvram config file variable is "
+ "going to be ignored.");
+ cfg->nfirmwares = 0;
+ return 0;
+ }
+
cfg->nfirmwares = virStringListLength((const char *const *)nvram);
if (nvram[0] && VIR_ALLOC_N(cfg->firmwares, cfg->nfirmwares) < 0)
return -1;
@@ -1041,7 +1056,7 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
if (virQEMUDriverConfigLoadLogEntry(cfg, conf) < 0)
return -1;
- if (virQEMUDriverConfigLoadNVRAMEntry(cfg, conf) < 0)
+ if (virQEMUDriverConfigLoadNVRAMEntry(cfg, conf, privileged) < 0)
return -1;
if (virQEMUDriverConfigLoadGlusterDebugEntry(cfg, conf) < 0)
--
2.23.0
5 years