[libvirt PATCH] qemu: Enable unprivileged userfaultfd for post-copy migration
by Jiri Denemark
Userfaultfd is by default allowed only for privileged processes. Since
libvirt runs QEMU unprivileged, we need to enable unprivileged access to
userfaultfd before starting post-copy migration.
Rather than providing a static sysctl configuration file, we set the
sysctl knob in runtime once post-copy migration is requested. This way
unprivileged_userfaultfd is only enabled once actually used.
https://bugzilla.redhat.com/show_bug.cgi?id=1945420
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/qemu/qemu_migration_params.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
index dbc3219826..a9449ed1ff 100644
--- a/src/qemu/qemu_migration_params.c
+++ b/src/qemu/qemu_migration_params.c
@@ -804,6 +804,24 @@ qemuMigrationCapsToJSON(virBitmap *caps,
}
+static void
+qemuMigrationParamsEnableUserfaultfd(virDomainObj *vm)
+{
+ const char *sysctl = "/proc/sys/vm/unprivileged_userfaultfd";
+
+ if (!virFileExists(sysctl))
+ return;
+
+ VIR_DEBUG("Enabling unprivileged userfaultfd for post-copy migration of "
+ "domain %s", vm->def->name);
+
+ if (virFileWriteStr(sysctl, "1", 0) < 0) {
+ virReportSystemError(errno, "%s",
+ _("failed to enable unprivileged userfaultfd"));
+ }
+}
+
+
/**
* qemuMigrationParamsApply
* @driver: qemu driver
@@ -839,6 +857,13 @@ qemuMigrationParamsApply(virQEMUDriver *driver,
goto cleanup;
}
} else {
+ /* userfaultfd may only be enabled for privileged processes by default,
+ * we need to make sure QEMU can use it before enabling post-copy
+ * migration */
+ if (virBitmapIsBitSet(priv->migrationCaps, QEMU_MIGRATION_CAP_POSTCOPY) &&
+ virBitmapIsBitSet(migParams->caps, QEMU_MIGRATION_CAP_POSTCOPY))
+ qemuMigrationParamsEnableUserfaultfd(vm);
+
if (!(caps = qemuMigrationCapsToJSON(priv->migrationCaps, migParams->caps)))
goto cleanup;
--
2.34.1
2 years, 11 months
[PATCH 0/3] qemu: Simplify qemuDomainGetStats() related code
by Michal Privoznik
*** BLURB HERE ***
Michal Prívozník (3):
qemu: Drop comma after QEMU_CAPS_LAST in queryDirtyRateRequired[]
qemu: prefer .requiredCaps for VIR_DOMAIN_STATS_IOTHREAD
qemuConnectGetAllDomainStats: Simplify qemuDomainGetStats() error
handling
src/qemu/qemu_driver.c | 36 ++++++++++++++++++------------------
1 file changed, 18 insertions(+), 18 deletions(-)
--
2.32.0
2 years, 11 months
[PATCH v2] virnetdevveth: Do report error if creating veth fails
by Michal Privoznik
For some weird reason we are ignoring errors when creating veth
pair that netlink reports. This affects the LXC driver which
creates interfaces for container in
virLXCProcessSetupInterfaces(). If creating a veth pair fails, no
error is reported and the control jumps onto cleanup label where
some cryptic error message is reported instead (something about
inability to remove veth pair).
Let's report error that netlink returned - it's probably the most
accurate reason anyways.
Resolves: https://gitlab.com/libvirt/libvirt/-/issues/225
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
v2 of:
https://listman.redhat.com/archives/libvir-list/2021-December/msg00016.html
diff to v1:
- Report error only if it wasn't already reported (error == 0)
src/util/virnetdevveth.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/src/util/virnetdevveth.c b/src/util/virnetdevveth.c
index 7133af44a2..b580e105ac 100644
--- a/src/util/virnetdevveth.c
+++ b/src/util/virnetdevveth.c
@@ -38,10 +38,19 @@ VIR_LOG_INIT("util.netdevveth");
static int
virNetDevVethCreateInternal(const char *veth1, const char *veth2)
{
- int status; /* Just ignore it */
+ int error = 0;
virNetlinkNewLinkData data = { .veth_peer = veth2 };
- return virNetlinkNewLink(veth1, "veth", &data, &status);
+ if (virNetlinkNewLink(veth1, "veth", &data, &error) < 0) {
+ if (error != 0) {
+ virReportSystemError(-error,
+ _("unable to create %s <-> %s veth pair"),
+ veth1, veth2);
+ }
+ return -1;
+ }
+
+ return 0;
}
static int
--
2.32.0
2 years, 11 months
[libvirt PATCH 0/9] WIP/RFC: add QEMU "-display dbus" support
by marcandre.lureau@redhat.com
From: Marc-André Lureau <marcandre.lureau(a)redhat.com>
Hi,
This series implements supports for the upcoming QEMU "-display dbus" support.
Development is still in progress, but I hope to land the QEMU support early in
6.3 (last version posted:
https://patchew.org/QEMU/20211009210838.2219430-1-marcandre.lureau@redhat...).
By default, libvirt will start a private VM bus (sharing and reusing the
existing "vmstate" code). A client will need the address of the bus and access
to it. Since D-Bus addresses are not URIs unfortunately, I am not sure yet what
should "virsh domdisplay" return.
The feature set should cover the needs to replace Spice as local client of choice,
including 3daccel/dmabuf, audio, clipboard sharing, usb redirection, and arbitrary
chardev/channels (for serial etc).
The test Gtk4 client is also in progress, currently in development at
https://gitlab.com/marcandre.lureau/qemu-display/. A few dependencies, such as
zbus, require an upcoming release. virt-viewer & boxes will need a port to Gtk4
to make use of the shared widget.
Comments welcome, as we can still adjust the QEMU side etc.
thanks
Marc-André Lureau (9):
qemu: start the D-Bus daemon as needed
qemu: add chardev-vdagent capability check
qemu: add -display dbus capability check (to update to 6.3)
qemu: add -display dbus support
qemu: add audio type 'dbus'
qemu: add dbus clipboard sharing
qemu: add -chardev dbus
qemu: add usbredir type 'dbus'
docs: document <graphics> type dbus
docs/formatdomain.rst | 24 ++++
docs/schemas/basictypes.rng | 7 ++
docs/schemas/domaincommon.rng | 71 +++++++++++
src/bhyve/bhyve_command.c | 1 +
src/conf/domain_conf.c | 116 +++++++++++++++++-
src/conf/domain_conf.h | 14 +++
src/conf/domain_validate.c | 32 +++--
src/libxl/libxl_conf.c | 1 +
src/qemu/qemu_capabilities.c | 6 +
src/qemu/qemu_capabilities.h | 2 +
src/qemu/qemu_command.c | 94 +++++++++++++-
src/qemu/qemu_domain.c | 1 +
src/qemu/qemu_domain.h | 1 +
src/qemu/qemu_driver.c | 10 +-
src/qemu/qemu_hotplug.c | 1 +
src/qemu/qemu_monitor_json.c | 1 +
src/qemu/qemu_process.c | 15 ++-
src/qemu/qemu_validate.c | 33 +++++
src/security/security_dac.c | 2 +
src/vmx/vmx.c | 1 +
.../domaincapsdata/qemu_6.2.0-q35.x86_64.xml | 1 +
.../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml | 1 +
tests/domaincapsdata/qemu_6.2.0.x86_64.xml | 1 +
.../caps_6.1.0.x86_64.xml | 1 +
.../caps_6.2.0.aarch64.xml | 1 +
.../caps_6.2.0.x86_64.replies | 10 +-
.../caps_6.2.0.x86_64.xml | 2 +
.../graphics-dbus-address.args | 31 +++++
.../graphics-dbus-address.xml | 34 +++++
.../qemuxml2argvdata/graphics-dbus-audio.args | 32 +++++
.../qemuxml2argvdata/graphics-dbus-audio.xml | 40 ++++++
.../graphics-dbus-chardev.args | 33 +++++
.../graphics-dbus-chardev.xml | 38 ++++++
.../graphics-dbus-clipboard.args | 32 +++++
.../graphics-dbus-clipboard.xml | 36 ++++++
tests/qemuxml2argvdata/graphics-dbus-p2p.args | 31 +++++
tests/qemuxml2argvdata/graphics-dbus-p2p.xml | 36 ++++++
.../graphics-dbus-usbredir.args | 35 ++++++
.../graphics-dbus-usbredir.xml | 36 ++++++
tests/qemuxml2argvdata/graphics-dbus.args | 31 +++++
tests/qemuxml2argvdata/graphics-dbus.xml | 34 +++++
tests/qemuxml2argvtest.c | 21 ++++
.../graphics-dbus-address.xml | 39 ++++++
.../graphics-dbus-audio.xml | 43 +++++++
.../qemuxml2xmloutdata/graphics-dbus-p2p.xml | 39 ++++++
tests/qemuxml2xmloutdata/graphics-dbus.xml | 39 ++++++
tests/qemuxml2xmltest.c | 14 +++
47 files changed, 1106 insertions(+), 18 deletions(-)
create mode 100644 tests/qemuxml2argvdata/graphics-dbus-address.args
create mode 100644 tests/qemuxml2argvdata/graphics-dbus-address.xml
create mode 100644 tests/qemuxml2argvdata/graphics-dbus-audio.args
create mode 100644 tests/qemuxml2argvdata/graphics-dbus-audio.xml
create mode 100644 tests/qemuxml2argvdata/graphics-dbus-chardev.args
create mode 100644 tests/qemuxml2argvdata/graphics-dbus-chardev.xml
create mode 100644 tests/qemuxml2argvdata/graphics-dbus-clipboard.args
create mode 100644 tests/qemuxml2argvdata/graphics-dbus-clipboard.xml
create mode 100644 tests/qemuxml2argvdata/graphics-dbus-p2p.args
create mode 100644 tests/qemuxml2argvdata/graphics-dbus-p2p.xml
create mode 100644 tests/qemuxml2argvdata/graphics-dbus-usbredir.args
create mode 100644 tests/qemuxml2argvdata/graphics-dbus-usbredir.xml
create mode 100644 tests/qemuxml2argvdata/graphics-dbus.args
create mode 100644 tests/qemuxml2argvdata/graphics-dbus.xml
create mode 100644 tests/qemuxml2xmloutdata/graphics-dbus-address.xml
create mode 100644 tests/qemuxml2xmloutdata/graphics-dbus-audio.xml
create mode 100644 tests/qemuxml2xmloutdata/graphics-dbus-p2p.xml
create mode 100644 tests/qemuxml2xmloutdata/graphics-dbus.xml
--
2.33.0.721.g106298f7f9
2 years, 11 months
[PATCH] virnetdevveth: Do report error if creating veth fails
by Michal Privoznik
For some weird reason we are ignoring errors when creating veth
pair that netlink reports. This affects the LXC driver which
creates interfaces for container in
virLXCProcessSetupInterfaces(). If creating a veth pair fails, no
error is reported and the control jumps onto cleanup label where
some cryptic error message is reported instead (something about
inability to remove veth pair).
Let's report error that netlink returned - it's probably the most
accurate reason anyways.
Resolves: https://gitlab.com/libvirt/libvirt/-/issues/225
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/util/virnetdevveth.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/util/virnetdevveth.c b/src/util/virnetdevveth.c
index 7133af44a2..ddf304036a 100644
--- a/src/util/virnetdevveth.c
+++ b/src/util/virnetdevveth.c
@@ -38,10 +38,17 @@ VIR_LOG_INIT("util.netdevveth");
static int
virNetDevVethCreateInternal(const char *veth1, const char *veth2)
{
- int status; /* Just ignore it */
+ int error;
virNetlinkNewLinkData data = { .veth_peer = veth2 };
- return virNetlinkNewLink(veth1, "veth", &data, &status);
+ if (virNetlinkNewLink(veth1, "veth", &data, &error) < 0) {
+ virReportSystemError(-error,
+ _("unable to create %s <-> %s veth pair"),
+ veth1, veth2);
+ return -1;
+ }
+
+ return 0;
}
static int
--
2.32.0
2 years, 11 months
[libvirt PATCH v7 0/3] Ignore EPERM on implicit clearing of VF VLAN ID
by Dmitrii Shcherbakov
SmartNIC DPUs may not expose some privileged eswitch operations
to the hypervisor hosts. For example, this happens with Bluefield
devices running in the ECPF (default) mode [1] for security reasons. While
VF MAC address programming is possible via an RTM_SETLINK operation,
trying to set a VLAN ID in the same operation will fail with EPERM.
In the kernel a relevant call chain may look like
do_setlink -> do_setvfinfo -> dev->netdev_ops->set_vf_vlan
which calls a driver-specific function like [2] eventually.
The equivalent ip link commands below provide an illustration:
1. This works:
sudo ip link set enp130s0f0 vf 2 mac de:ad:be:ef:ca:fe
2. Setting (or clearing) a VLAN fails with EPERM:
sudo ip link set enp130s0f0 vf 2 vlan 0
RTNETLINK answers: Operation not permitted
3. This is what Libvirt attempts to do today (when trying to clear a
VF VLAN at the same time as programming a VF MAC).
sudo ip link set enp130s0f0 vf 2 vlan 0 mac de:ad:be:ef:ca:fe
RTNETLINK answers: Operation not permitted
If setting an explicit VLAN ID results in an EPERM, clearing a VLAN
(setting a VLAN ID to 0) can be handled gracefully by ignoring the
EPERM error with the rationale being that if we cannot set this state
in the first place, we cannot clear it either.
Thus, virNetDevSetVfConfig is split into two distinct functions. If
clearing a VLAN ID fails with EPERM when clearing is implicit, the
error is simply ignored. For explicit clearing EPERM is still a
fatal error.
Both new functions rely virNetDevSendVfSetLinkRequest that implements
common functionality related to formatting a request, sending it and
handling error conditions and returns 0 or an error since in both cases
the payload is either NLMSG_DONE (no error) or NLMSG_ERROR where an
error message is needed by the caller to handle known cases
appropriately. This function allows the conditional code to be unit tested.
An alternative to this could be providing a higher level control plane
mechanism that would provide metadata about a device being remotely
managed in which case Libvirt would avoid trying to set or clear a
VLAN ID. This would be more complicated since other software (like Nova
in the OpenStack case) would have to annotate every guest device with an
attribute indicating whether a device is remotely managed or not based
on operator provided configuration so that Libvirt can act on this and
avoid VLAN programming.
https://gitlab.com/dmitriis/libvirt/-/pipelines/420603489
v4 changes:
* Split the change into several patches;
* Added a missing test case;
* Reworked error handling;
* Added a way to pass a NULL vlan id to preserve the old behavior
when needed.
v5 changes:
* added the news file entry;
* fixed vlan handling in virNetDevSetVfVlan (for an issue introduced in v4).
v6 changes:
Refactoring, addressed:
https://listman.redhat.com/archives/libvir-list/2021-November/msg00521.html
v7 change:
* Rebased on top of the latest changes;
* Added stubs for platforms without libnl (fixed Windows builds).
[1] https://docs.mellanox.com/display/BlueFieldSWv35111601/Modes+of+Operation...
[2] https://github.com/torvalds/linux/blob/v5.15/drivers/net/ethernet/mellano...
Dmitrii Shcherbakov (3):
Set VF MAC and VLAN ID in two different operations
Allow VF vlanid to be passed as a pointer
Ignore EPERM on implicit clearing of VF VLAN ID
NEWS.rst | 14 ++
src/hypervisor/virhostdev.c | 4 +-
src/libvirt_private.syms | 7 +
src/util/virnetdev.c | 256 +++++++++++++++++++++++++-----------
src/util/virnetdevpriv.h | 44 +++++++
tests/virnetdevtest.c | 249 ++++++++++++++++++++++++++++++++++-
6 files changed, 496 insertions(+), 78 deletions(-)
create mode 100644 src/util/virnetdevpriv.h
--
2.32.0
2 years, 11 months
[PATCH] util: fix erroneous requirement for phys_port_id to get ifname of a VF
by Laine Stump
Commit 795e9e05c3 (libvirt-7.7.0) refactored the code in virpci.c and
virnetdev.c that gathered lists of the Virtual Functions (VF) of an
SRIOV Physical Function (PF) to simplify the code.
Unfortunately the simplification made the assumption that a VF's
netdev interface name should only be retrieved if the PF had a valid
phys_port_id. That is an incorrect assumption - only a small handful
of (now previous-generation) Mellanox SRIOV cards actually use
phys_port_id (this is for an odd design where there are multiple
physical network ports on a single PCI address); all other SRIOV cards
(including new Mellanox cards) have a file in sysfs called
phys_port_id, but it can't be read, and so the pfPhysPortID string is
NULL.
The result of this logic error is that virtual networks that are a
pool of VFs to be used for macvtap connections will be unable to
start, giving an errror like this:
VF 0 of SRIOV PF enp130s0f0 couldn't be added to the interface pool because it isn't bound to a network driver - possibly in use elsewhere
The simple/quick solution to this is to not imply that "pfPhysPortID
== NULL" is the same as "don't fill in the VF's netdev
ifname". Instead, add a bool getIfName to the args of
virNetDevGetVirtualFunctionsFull() so that we can still get the ifname
filled in when pfPhysPortID is NULL.
Resolves: https://bugzilla.redhat.com/2025432
Fixes: 795e9e05c3b6b9ef3abe6f6078a6373a136ec23b
Signed-off-by: Laine Stump <laine(a)redhat.com>
---
On one hand this is a regression with an apparently simple fix (that
has been tested to solve the problem), and it's always good to fix
regressions before a release rather than after. On the other hand it
has been broken since August, and nobody complained until last week
(and that was a QE tester, not an actual end-user), so it seems the
bug is in functionality that isn't used much in the field (or at least
no downstream with a used of the functionality has made a release
since then that was installed by said user).
I've grown increasingly wary of pushing anything just before a
release, especially when it modifies the args of a function that has
multiple definitions for different platforms (although CI is supposed
to be thorough enough to catch those types of problems these days). So
I'm all for pushing this right after the release, rather than
before. But if anyone sees a reason for doing otherwise, we can talk
about it in about 10 hours when I sit down at the keyboard again :-).
P.S. I'm planning to make a followup that eliminates the pfPhysPortID
arg completely, but wanted the bugfix to be as stripped down as
possible.
src/util/virnetdev.c | 2 +-
src/util/virpci.c | 20 ++++++++++++--------
src/util/virpci.h | 1 +
3 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index 58f7360a0f..300d7e4f45 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -1231,7 +1231,7 @@ virNetDevGetVirtualFunctions(const char *pfname,
if (virNetDevSysfsFile(&pf_sysfs_device_link, pfname, "device") < 0)
return -1;
- if (virPCIGetVirtualFunctionsFull(pf_sysfs_device_link, vfs, pfPhysPortID) < 0)
+ if (virPCIGetVirtualFunctionsFull(pf_sysfs_device_link, true, vfs, pfPhysPortID) < 0)
return -1;
return 0;
diff --git a/src/util/virpci.c b/src/util/virpci.c
index 2d12e28004..b7b987dd63 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -2263,7 +2263,7 @@ int
virPCIGetVirtualFunctions(const char *sysfs_path,
virPCIVirtualFunctionList **vfs)
{
- return virPCIGetVirtualFunctionsFull(sysfs_path, vfs, NULL);
+ return virPCIGetVirtualFunctionsFull(sysfs_path, false, vfs, NULL);
}
@@ -2339,15 +2339,18 @@ virPCIGetPhysicalFunction(const char *vf_sysfs_path,
/**
* virPCIGetVirtualFunctionsFull:
* @sysfs_path: path to physical function sysfs entry
+ * @getIfName: true if the ifname of the VF should also be filled in,
+ * false to only fill in the PCI address.
* @vfs: filled with the virtual function data
- * @pfPhysPortID: Optional physical port id. If provided the network interface
- * name of the VFs is queried too.
+ * @pfPhysPortID: Optional physical port id. if non-null it will be used
+ * when determining the ifname.
*
*
* Returns virtual functions of a physical function.
*/
int
virPCIGetVirtualFunctionsFull(const char *sysfs_path,
+ bool getIfName,
virPCIVirtualFunctionList **vfs,
const char *pfPhysPortID)
{
@@ -2390,11 +2393,10 @@ virPCIGetVirtualFunctionsFull(const char *sysfs_path,
return -1;
}
- if (pfPhysPortID) {
- if (virPCIGetNetName(device_link, 0, pfPhysPortID, &fnc.ifname) < 0) {
- g_free(fnc.addr);
- return -1;
- }
+ if (getIfName &&
+ virPCIGetNetName(device_link, 0, pfPhysPortID, &fnc.ifname) < 0) {
+ g_free(fnc.addr);
+ return -1;
}
VIR_APPEND_ELEMENT(list->functions, list->nfunctions, fnc);
@@ -2711,8 +2713,10 @@ virPCIGetPhysicalFunction(const char *vf_sysfs_path G_GNUC_UNUSED,
int
virPCIGetVirtualFunctionsFull(const char *sysfs_path G_GNUC_UNUSED,
+ bool getIfName G_GNUC_UNUSED,
virPCIVirtualFunctionList **vfs G_GNUC_UNUSED,
const char *pfPhysPortID G_GNUC_UNUSED)
+
{
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
return -1;
diff --git a/src/util/virpci.h b/src/util/virpci.h
index 3346321ec9..2f64c447cc 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -229,6 +229,7 @@ void virPCIVirtualFunctionListFree(virPCIVirtualFunctionList *list);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIVirtualFunctionList, virPCIVirtualFunctionListFree);
int virPCIGetVirtualFunctionsFull(const char *sysfs_path,
+ bool getIfName,
virPCIVirtualFunctionList **vfs,
const char *pfPhysPortID);
int virPCIGetVirtualFunctions(const char *sysfs_path,
--
2.33.1
2 years, 11 months
[PATCH] qemu_domainjob: move jobs_queued to struct qemuDomainJobObj
by Kristina Hanicova
I think it makes more sense for the variable about jobs to be in
the job object. I also renamed it to be consistent with the rest
of the struct.
Signed-off-by: Kristina Hanicova <khanicov(a)redhat.com>
---
Not gonna lie, it will make my planned generalization of jobs
much easier as well.
src/qemu/qemu_domain.h | 2 --
src/qemu/qemu_domainjob.c | 14 +++++++-------
src/qemu/qemu_domainjob.h | 2 ++
src/qemu/qemu_process.c | 2 +-
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 6728ab047e..913c20b941 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -141,8 +141,6 @@ struct _qemuDomainObjPrivate {
*/
virTristateBool allowReboot;
- int jobs_queued;
-
unsigned long migMaxBandwidth;
char *origname;
int nbdPort; /* Port used for migration with NBD */
diff --git a/src/qemu/qemu_domainjob.c b/src/qemu/qemu_domainjob.c
index cff8d7bb83..62fa09921b 100644
--- a/src/qemu/qemu_domainjob.c
+++ b/src/qemu/qemu_domainjob.c
@@ -847,13 +847,13 @@ qemuDomainObjBeginJobInternal(virQEMUDriver *driver,
if (virTimeMillisNow(&now) < 0)
return -1;
- priv->jobs_queued++;
+ priv->job.jobsQueued++;
then = now + QEMU_JOB_WAIT_TIME;
retry:
if ((!async && job != QEMU_JOB_DESTROY) &&
cfg->maxQueuedJobs &&
- priv->jobs_queued > cfg->maxQueuedJobs) {
+ priv->job.jobsQueued > cfg->maxQueuedJobs) {
goto error;
}
@@ -986,7 +986,7 @@ qemuDomainObjBeginJobInternal(virQEMUDriver *driver,
}
ret = -2;
} else if (cfg->maxQueuedJobs &&
- priv->jobs_queued > cfg->maxQueuedJobs) {
+ priv->job.jobsQueued > cfg->maxQueuedJobs) {
if (blocker && agentBlocker) {
virReportError(VIR_ERR_OPERATION_FAILED,
_("cannot acquire state change "
@@ -1016,7 +1016,7 @@ qemuDomainObjBeginJobInternal(virQEMUDriver *driver,
}
cleanup:
- priv->jobs_queued--;
+ priv->job.jobsQueued--;
return ret;
}
@@ -1136,7 +1136,7 @@ qemuDomainObjEndJob(virQEMUDriver *driver, virDomainObj *obj)
qemuDomainObjPrivate *priv = obj->privateData;
qemuDomainJob job = priv->job.active;
- priv->jobs_queued--;
+ priv->job.jobsQueued--;
VIR_DEBUG("Stopping job: %s (async=%s vm=%p name=%s)",
qemuDomainJobTypeToString(job),
@@ -1157,7 +1157,7 @@ qemuDomainObjEndAgentJob(virDomainObj *obj)
qemuDomainObjPrivate *priv = obj->privateData;
qemuDomainAgentJob agentJob = priv->job.agentActive;
- priv->jobs_queued--;
+ priv->job.jobsQueued--;
VIR_DEBUG("Stopping agent job: %s (async=%s vm=%p name=%s)",
qemuDomainAgentJobTypeToString(agentJob),
@@ -1175,7 +1175,7 @@ qemuDomainObjEndAsyncJob(virQEMUDriver *driver, virDomainObj *obj)
{
qemuDomainObjPrivate *priv = obj->privateData;
- priv->jobs_queued--;
+ priv->job.jobsQueued--;
VIR_DEBUG("Stopping async job: %s (vm=%p name=%s)",
qemuDomainAsyncJobTypeToString(priv->job.asyncJob),
diff --git a/src/qemu/qemu_domainjob.h b/src/qemu/qemu_domainjob.h
index 46cbb8a067..cfef1ff462 100644
--- a/src/qemu/qemu_domainjob.h
+++ b/src/qemu/qemu_domainjob.h
@@ -176,6 +176,8 @@ struct _qemuDomainObjPrivateJobCallbacks {
struct _qemuDomainJobObj {
virCond cond; /* Use to coordinate jobs */
+ int jobsQueued;
+
/* The following members are for QEMU_JOB_* */
qemuDomainJob active; /* Currently running job */
unsigned long long owner; /* Thread id which set current job */
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index c355a39e15..3b07f52954 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3745,7 +3745,7 @@ qemuProcessRecoverJob(virQEMUDriver *driver,
ignore_value(virTimeMillisNow(&now));
/* Restore the config of the async job which is not persisted */
- priv->jobs_queued++;
+ priv->job.jobsQueued++;
priv->job.asyncJob = QEMU_ASYNC_JOB_BACKUP;
priv->job.asyncOwnerAPI = g_strdup(virThreadJobGet());
priv->job.asyncStarted = now;
--
2.31.1
2 years, 11 months