[libvirt PATCH 0/4] misc fixes for GCC 10
by Daniel P. Berrangé
This fixes problem that exhibit themselves with GCC 10,
either the Debian Sid cross-compilers on 32-bit, or
with Fedora rawhide mingw.
Daniel P. Berrangé (4):
util: refactor code to workaround gcc 10.1.0 bug
m4: enable -fstack-protector-strong on mingw
tests: don't mock the time() function on mingw
tools: be more paranoid about possibly NULL description
m4/virt-compile-warnings.m4 | 4 +---
src/util/virnetdevip.c | 17 ++++++++---------
tests/virnetdaemonmock.c | 2 ++
tools/vsh.c | 2 +-
4 files changed, 12 insertions(+), 13 deletions(-)
--
2.24.1
4 years, 5 months
[libvirt PATCH 0/3] vmx: fix handling of VMX MAC address options
by Daniel P. Berrangé
We first had a proposal to add a "check" attribute for MAC addresses
https://www.redhat.com/archives/libvir-list/2020-July/msg00617.html
For reasons I don't understand this was then replaced by a "type"
attribute
https://www.redhat.com/archives/libvir-list/2020-July/msg00656.html
with the "type" attribute having the side-effect of changing the
VMX checkMACAddress config. See the first patch for more detailed
description of the flaws.
The core problem with the original VMX code before either of these
patches was that we have multiple distinct VMX config settings and
they were all being overloaded into a single MAC address attribute
in the XML. This overloading is inherantly loosing information so
cannot be reliably round-trippped.
The only way to solve this is to actually have explicit attributes
for the config parameters from VMX and stop overloading things.
IOW, we needed *both* the "check" and "type" attributes.
That is what this series does. It also adds the missing VMX -> XML
conversion step so we round-trip everything.
There are still some pieces that are not perfect.
- libvirt has type=static|generated, but VMX has
type=static|generated|vpx. "vpx" is just a synonym for
"generated", but using a different MAC addr range. We
use the range to do the mapping, and can probablylive
with that.
- VMX has a a address offset field - I've not found any
info on what this is needed for, but we hardcode it
to 0 for XML -> VMX config, and ignore it entirely
for VMX -> XML config. This means we won't roundtrip
this setting. This needs fixing if anyone expects
we'll see offset != 0 in the real world.
Bastien Orivel (1):
Add a check attribute on the mac address element
Daniel P. Berrangé (2):
vmx: fix logic handling mac address type
vmx: support outputing the type attribute for MAC addresses
docs/schemas/domaincommon.rng | 5 ++
src/conf/domain_conf.c | 14 ++++
src/conf/domain_conf.h | 1 +
src/vmx/vmx.c | 77 ++++++++++++++-----
.../network-interface-mac-check.xml | 29 +++++++
tests/genericxml2xmltest.c | 2 +
.../vmx2xml-case-insensitive-1.xml | 2 +-
.../vmx2xml-case-insensitive-2.xml | 2 +-
.../vmx2xmldata/vmx2xml-esx-in-the-wild-1.xml | 2 +-
.../vmx2xmldata/vmx2xml-esx-in-the-wild-2.xml | 2 +-
.../vmx2xmldata/vmx2xml-esx-in-the-wild-3.xml | 2 +-
.../vmx2xmldata/vmx2xml-esx-in-the-wild-4.xml | 4 +-
.../vmx2xmldata/vmx2xml-esx-in-the-wild-5.xml | 2 +-
.../vmx2xmldata/vmx2xml-esx-in-the-wild-6.xml | 2 +-
.../vmx2xmldata/vmx2xml-esx-in-the-wild-7.xml | 2 +-
.../vmx2xmldata/vmx2xml-esx-in-the-wild-8.xml | 20 ++---
.../vmx2xmldata/vmx2xml-esx-in-the-wild-9.xml | 2 +-
.../vmx2xmldata/vmx2xml-ethernet-bridged.xml | 2 +-
tests/vmx2xmldata/vmx2xml-ethernet-custom.xml | 2 +-
tests/vmx2xmldata/vmx2xml-ethernet-e1000.xml | 2 +-
.../vmx2xml-ethernet-generated.xml | 2 +-
tests/vmx2xmldata/vmx2xml-ethernet-nat.xml | 2 +-
tests/vmx2xmldata/vmx2xml-ethernet-other.xml | 2 +-
tests/vmx2xmldata/vmx2xml-ethernet-static.xml | 2 +-
.../vmx2xmldata/vmx2xml-ethernet-vmxnet2.xml | 2 +-
tests/vmx2xmldata/vmx2xml-ethernet-vpx.xml | 2 +-
.../vmx2xml-fusion-in-the-wild-1.xml | 4 +-
.../vmx2xmldata/vmx2xml-gsx-in-the-wild-1.xml | 2 +-
.../vmx2xmldata/vmx2xml-gsx-in-the-wild-2.xml | 2 +-
.../vmx2xmldata/vmx2xml-gsx-in-the-wild-3.xml | 4 +-
.../vmx2xmldata/vmx2xml-gsx-in-the-wild-4.xml | 2 +-
.../vmx2xmldata/vmx2xml-ws-in-the-wild-1.xml | 2 +-
.../vmx2xmldata/vmx2xml-ws-in-the-wild-2.xml | 2 +-
.../xml2vmxdata/xml2vmx-ethernet-mac-type.vmx | 7 +-
.../xml2vmxdata/xml2vmx-ethernet-mac-type.xml | 4 +-
35 files changed, 154 insertions(+), 63 deletions(-)
create mode 100644 tests/genericxml2xmlindata/network-interface-mac-check.xml
--
2.24.1
4 years, 5 months
[libvirt PATCH] ci: Run 'make distcheck' on FreeBSD
by Andrea Bolognani
The Cirrus CI integration was modeled after the Travis CI jobs,
but those were limited to macOS where the test suite is currently
still broken. FreeBSD can run the full distcheck just fine, so
let's do that.
Fixes: 6190c14151c3e2cf5c30b9df9131697f5c3b64b9
Signed-off-by: Andrea Bolognani <abologna(a)redhat.com>
---
Test pipeline:
https://gitlab.com/abologna/libvirt/-/pipelines/169877021
ci/cirrus/build.yml | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/ci/cirrus/build.yml b/ci/cirrus/build.yml
index 893e13d724..b7524021b4 100644
--- a/ci/cirrus/build.yml
+++ b/ci/cirrus/build.yml
@@ -21,6 +21,5 @@ build_task:
- mkdir build
- cd build
- ../autogen.sh --prefix=$(pwd)/install-root
- - $MAKE -j3
- - $MAKE -j3 install
- - $MAKE -j3 dist
+ - if test "$(uname)" = "FreeBSD"; then $MAKE -j3 distcheck; fi
+ - if test "$(uname)" = "Darwin"; then $MAKE -j3 && $MAKE -j3 install && $MAKE -j3 dist; fi
--
2.25.4
4 years, 5 months
[GSoC][PATCH] qemu_domain: Added `qemuDomainJobInfo` to domainJob's `privateData`
by Prathamesh Chavan
As `qemuDomainJobInfo` had attributes specific to qemu hypervisor's
jobs, we added it to `privateData` structure.
Supporting functions of `qemuDomainJobInfo` were also moved from
`qemu_domainjob` to `qemu_domain`.
Functions `qemuDomainCurrentJobInfoInit` and
`qemuDomainJobInfoSetOperation` were introduced in this
process.
Signed-off-by: Prathamesh Chavan <pc44800(a)gmail.com>
---
src/qemu/qemu_backup.c | 22 +-
src/qemu/qemu_domain.c | 496 +++++++++++++++++++++++++++++++
src/qemu/qemu_domain.h | 67 +++++
src/qemu/qemu_domainjob.c | 483 +-----------------------------
src/qemu/qemu_domainjob.h | 58 ----
src/qemu/qemu_driver.c | 49 +--
src/qemu/qemu_migration.c | 62 ++--
src/qemu/qemu_migration_cookie.c | 8 +-
src/qemu/qemu_process.c | 32 +-
9 files changed, 665 insertions(+), 612 deletions(-)
diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
index a402730d38..1822c6f267 100644
--- a/src/qemu/qemu_backup.c
+++ b/src/qemu/qemu_backup.c
@@ -529,20 +529,21 @@ qemuBackupJobTerminate(virDomainObjPtr vm,
{
qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
size_t i;
- qemuDomainJobInfoUpdateTime(priv->job.current);
+ qemuDomainJobInfoUpdateTime(jobPriv->current);
- g_clear_pointer(&priv->job.completed, qemuDomainJobInfoFree);
- priv->job.completed = qemuDomainJobInfoCopy(priv->job.current);
+ g_clear_pointer(&jobPriv->completed, qemuDomainJobInfoFree);
+ jobPriv->completed = qemuDomainJobInfoCopy(jobPriv->current);
- priv->job.completed->stats.backup.total = priv->backup->push_total;
- priv->job.completed->stats.backup.transferred = priv->backup->push_transferred;
- priv->job.completed->stats.backup.tmp_used = priv->backup->pull_tmp_used;
- priv->job.completed->stats.backup.tmp_total = priv->backup->pull_tmp_total;
+ jobPriv->completed->stats.backup.total = priv->backup->push_total;
+ jobPriv->completed->stats.backup.transferred = priv->backup->push_transferred;
+ jobPriv->completed->stats.backup.tmp_used = priv->backup->pull_tmp_used;
+ jobPriv->completed->stats.backup.tmp_total = priv->backup->pull_tmp_total;
- priv->job.completed->status = jobstatus;
- priv->job.completed->errmsg = g_strdup(priv->backup->errmsg);
+ jobPriv->completed->status = jobstatus;
+ jobPriv->completed->errmsg = g_strdup(priv->backup->errmsg);
qemuDomainEventEmitJobCompleted(priv->driver, vm);
@@ -694,6 +695,7 @@ qemuBackupBegin(virDomainObjPtr vm,
unsigned int flags)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(priv->driver);
g_autoptr(virDomainBackupDef) def = NULL;
g_autofree char *suffix = NULL;
@@ -745,7 +747,7 @@ qemuBackupBegin(virDomainObjPtr vm,
qemuDomainObjSetAsyncJobMask(vm, (QEMU_JOB_DEFAULT_MASK |
JOB_MASK(QEMU_JOB_SUSPEND) |
JOB_MASK(QEMU_JOB_MODIFY)));
- priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP;
+ jobPriv->current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP;
if (!virDomainObjIsActive(vm)) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 5b22eb2eaa..e4b5e2a94a 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -89,6 +89,457 @@ VIR_ENUM_IMPL(qemuDomainNamespace,
);
+static virDomainJobType
+qemuDomainJobStatusToType(qemuDomainJobStatus status)
+{
+ switch (status) {
+ case QEMU_DOMAIN_JOB_STATUS_NONE:
+ break;
+
+ case QEMU_DOMAIN_JOB_STATUS_ACTIVE:
+ case QEMU_DOMAIN_JOB_STATUS_MIGRATING:
+ case QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED:
+ case QEMU_DOMAIN_JOB_STATUS_POSTCOPY:
+ case QEMU_DOMAIN_JOB_STATUS_PAUSED:
+ return VIR_DOMAIN_JOB_UNBOUNDED;
+
+ case QEMU_DOMAIN_JOB_STATUS_COMPLETED:
+ return VIR_DOMAIN_JOB_COMPLETED;
+
+ case QEMU_DOMAIN_JOB_STATUS_FAILED:
+ return VIR_DOMAIN_JOB_FAILED;
+
+ case QEMU_DOMAIN_JOB_STATUS_CANCELED:
+ return VIR_DOMAIN_JOB_CANCELLED;
+ }
+
+ return VIR_DOMAIN_JOB_NONE;
+}
+
+int
+qemuDomainJobInfoUpdateTime(qemuDomainJobInfoPtr jobInfo)
+{
+ unsigned long long now;
+
+ if (!jobInfo->started)
+ return 0;
+
+ if (virTimeMillisNow(&now) < 0)
+ return -1;
+
+ if (now < jobInfo->started) {
+ VIR_WARN("Async job starts in the future");
+ jobInfo->started = 0;
+ return 0;
+ }
+
+ jobInfo->timeElapsed = now - jobInfo->started;
+ return 0;
+}
+
+int
+qemuDomainJobInfoUpdateDowntime(qemuDomainJobInfoPtr jobInfo)
+{
+ unsigned long long now;
+
+ if (!jobInfo->stopped)
+ return 0;
+
+ if (virTimeMillisNow(&now) < 0)
+ return -1;
+
+ if (now < jobInfo->stopped) {
+ VIR_WARN("Guest's CPUs stopped in the future");
+ jobInfo->stopped = 0;
+ return 0;
+ }
+
+ jobInfo->stats.mig.downtime = now - jobInfo->stopped;
+ jobInfo->stats.mig.downtime_set = true;
+ return 0;
+}
+
+
+int
+qemuDomainJobInfoToInfo(qemuDomainJobInfoPtr jobInfo,
+ virDomainJobInfoPtr info)
+{
+ info->type = qemuDomainJobStatusToType(jobInfo->status);
+ info->timeElapsed = jobInfo->timeElapsed;
+
+ switch (jobInfo->statsType) {
+ case QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION:
+ info->memTotal = jobInfo->stats.mig.ram_total;
+ info->memRemaining = jobInfo->stats.mig.ram_remaining;
+ info->memProcessed = jobInfo->stats.mig.ram_transferred;
+ info->fileTotal = jobInfo->stats.mig.disk_total +
+ jobInfo->mirrorStats.total;
+ info->fileRemaining = jobInfo->stats.mig.disk_remaining +
+ (jobInfo->mirrorStats.total -
+ jobInfo->mirrorStats.transferred);
+ info->fileProcessed = jobInfo->stats.mig.disk_transferred +
+ jobInfo->mirrorStats.transferred;
+ break;
+
+ case QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP:
+ info->memTotal = jobInfo->stats.mig.ram_total;
+ info->memRemaining = jobInfo->stats.mig.ram_remaining;
+ info->memProcessed = jobInfo->stats.mig.ram_transferred;
+ break;
+
+ case QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP:
+ info->memTotal = jobInfo->stats.dump.total;
+ info->memProcessed = jobInfo->stats.dump.completed;
+ info->memRemaining = info->memTotal - info->memProcessed;
+ break;
+
+ case QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP:
+ info->fileTotal = jobInfo->stats.backup.total;
+ info->fileProcessed = jobInfo->stats.backup.transferred;
+ info->fileRemaining = info->fileTotal - info->fileProcessed;
+ break;
+
+ case QEMU_DOMAIN_JOB_STATS_TYPE_NONE:
+ break;
+ }
+
+ info->dataTotal = info->memTotal + info->fileTotal;
+ info->dataRemaining = info->memRemaining + info->fileRemaining;
+ info->dataProcessed = info->memProcessed + info->fileProcessed;
+
+ return 0;
+}
+
+
+static int
+qemuDomainMigrationJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
+ int *type,
+ virTypedParameterPtr *params,
+ int *nparams)
+{
+ qemuMonitorMigrationStats *stats = &jobInfo->stats.mig;
+ qemuDomainMirrorStatsPtr mirrorStats = &jobInfo->mirrorStats;
+ virTypedParameterPtr par = NULL;
+ int maxpar = 0;
+ int npar = 0;
+ unsigned long long mirrorRemaining = mirrorStats->total -
+ mirrorStats->transferred;
+
+ if (virTypedParamsAddInt(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_OPERATION,
+ jobInfo->operation) < 0)
+ goto error;
+
+ if (virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_TIME_ELAPSED,
+ jobInfo->timeElapsed) < 0)
+ goto error;
+
+ if (jobInfo->timeDeltaSet &&
+ jobInfo->timeElapsed > jobInfo->timeDelta &&
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_TIME_ELAPSED_NET,
+ jobInfo->timeElapsed - jobInfo->timeDelta) < 0)
+ goto error;
+
+ if (stats->downtime_set &&
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_DOWNTIME,
+ stats->downtime) < 0)
+ goto error;
+
+ if (stats->downtime_set &&
+ jobInfo->timeDeltaSet &&
+ stats->downtime > jobInfo->timeDelta &&
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_DOWNTIME_NET,
+ stats->downtime - jobInfo->timeDelta) < 0)
+ goto error;
+
+ if (stats->setup_time_set &&
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_SETUP_TIME,
+ stats->setup_time) < 0)
+ goto error;
+
+ if (virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_DATA_TOTAL,
+ stats->ram_total +
+ stats->disk_total +
+ mirrorStats->total) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_DATA_PROCESSED,
+ stats->ram_transferred +
+ stats->disk_transferred +
+ mirrorStats->transferred) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_DATA_REMAINING,
+ stats->ram_remaining +
+ stats->disk_remaining +
+ mirrorRemaining) < 0)
+ goto error;
+
+ if (virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_TOTAL,
+ stats->ram_total) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_PROCESSED,
+ stats->ram_transferred) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_REMAINING,
+ stats->ram_remaining) < 0)
+ goto error;
+
+ if (stats->ram_bps &&
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_BPS,
+ stats->ram_bps) < 0)
+ goto error;
+
+ if (stats->ram_duplicate_set) {
+ if (virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_CONSTANT,
+ stats->ram_duplicate) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_NORMAL,
+ stats->ram_normal) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_NORMAL_BYTES,
+ stats->ram_normal_bytes) < 0)
+ goto error;
+ }
+
+ if (virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_DIRTY_RATE,
+ stats->ram_dirty_rate) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_ITERATION,
+ stats->ram_iteration) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_POSTCOPY_REQS,
+ stats->ram_postcopy_reqs) < 0)
+ goto error;
+
+ if (stats->ram_page_size > 0 &&
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_PAGE_SIZE,
+ stats->ram_page_size) < 0)
+ goto error;
+
+ /* The remaining stats are disk, mirror, or migration specific
+ * so if this is a SAVEDUMP, we can just skip them */
+ if (jobInfo->statsType == QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP)
+ goto done;
+
+ if (virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_DISK_TOTAL,
+ stats->disk_total +
+ mirrorStats->total) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_DISK_PROCESSED,
+ stats->disk_transferred +
+ mirrorStats->transferred) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_DISK_REMAINING,
+ stats->disk_remaining +
+ mirrorRemaining) < 0)
+ goto error;
+
+ if (stats->disk_bps &&
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_DISK_BPS,
+ stats->disk_bps) < 0)
+ goto error;
+
+ if (stats->xbzrle_set) {
+ if (virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_COMPRESSION_CACHE,
+ stats->xbzrle_cache_size) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_COMPRESSION_BYTES,
+ stats->xbzrle_bytes) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_COMPRESSION_PAGES,
+ stats->xbzrle_pages) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_COMPRESSION_CACHE_MISSES,
+ stats->xbzrle_cache_miss) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_COMPRESSION_OVERFLOW,
+ stats->xbzrle_overflow) < 0)
+ goto error;
+ }
+
+ if (stats->cpu_throttle_percentage &&
+ virTypedParamsAddInt(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_AUTO_CONVERGE_THROTTLE,
+ stats->cpu_throttle_percentage) < 0)
+ goto error;
+
+ done:
+ *type = qemuDomainJobStatusToType(jobInfo->status);
+ *params = par;
+ *nparams = npar;
+ return 0;
+
+ error:
+ virTypedParamsFree(par, npar);
+ return -1;
+}
+
+
+static int
+qemuDomainDumpJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
+ int *type,
+ virTypedParameterPtr *params,
+ int *nparams)
+{
+ qemuMonitorDumpStats *stats = &jobInfo->stats.dump;
+ virTypedParameterPtr par = NULL;
+ int maxpar = 0;
+ int npar = 0;
+
+ if (virTypedParamsAddInt(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_OPERATION,
+ jobInfo->operation) < 0)
+ goto error;
+
+ if (virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_TIME_ELAPSED,
+ jobInfo->timeElapsed) < 0)
+ goto error;
+
+ if (virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_TOTAL,
+ stats->total) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_PROCESSED,
+ stats->completed) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_REMAINING,
+ stats->total - stats->completed) < 0)
+ goto error;
+
+ *type = qemuDomainJobStatusToType(jobInfo->status);
+ *params = par;
+ *nparams = npar;
+ return 0;
+
+ error:
+ virTypedParamsFree(par, npar);
+ return -1;
+}
+
+
+static int
+qemuDomainBackupJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
+ int *type,
+ virTypedParameterPtr *params,
+ int *nparams)
+{
+ qemuDomainBackupStats *stats = &jobInfo->stats.backup;
+ g_autoptr(virTypedParamList) par = g_new0(virTypedParamList, 1);
+
+ if (virTypedParamListAddInt(par, jobInfo->operation,
+ VIR_DOMAIN_JOB_OPERATION) < 0)
+ return -1;
+
+ if (virTypedParamListAddULLong(par, jobInfo->timeElapsed,
+ VIR_DOMAIN_JOB_TIME_ELAPSED) < 0)
+ return -1;
+
+ if (stats->transferred > 0 || stats->total > 0) {
+ if (virTypedParamListAddULLong(par, stats->total,
+ VIR_DOMAIN_JOB_DISK_TOTAL) < 0)
+ return -1;
+
+ if (virTypedParamListAddULLong(par, stats->transferred,
+ VIR_DOMAIN_JOB_DISK_PROCESSED) < 0)
+ return -1;
+
+ if (virTypedParamListAddULLong(par, stats->total - stats->transferred,
+ VIR_DOMAIN_JOB_DISK_REMAINING) < 0)
+ return -1;
+ }
+
+ if (stats->tmp_used > 0 || stats->tmp_total > 0) {
+ if (virTypedParamListAddULLong(par, stats->tmp_used,
+ VIR_DOMAIN_JOB_DISK_TEMP_USED) < 0)
+ return -1;
+
+ if (virTypedParamListAddULLong(par, stats->tmp_total,
+ VIR_DOMAIN_JOB_DISK_TEMP_TOTAL) < 0)
+ return -1;
+ }
+
+ if (jobInfo->status != QEMU_DOMAIN_JOB_STATUS_ACTIVE &&
+ virTypedParamListAddBoolean(par,
+ jobInfo->status == QEMU_DOMAIN_JOB_STATUS_COMPLETED,
+ VIR_DOMAIN_JOB_SUCCESS) < 0)
+ return -1;
+
+ if (jobInfo->errmsg &&
+ virTypedParamListAddString(par, jobInfo->errmsg, VIR_DOMAIN_JOB_ERRMSG) < 0)
+ return -1;
+
+ *nparams = virTypedParamListStealParams(par, params);
+ *type = qemuDomainJobStatusToType(jobInfo->status);
+ return 0;
+}
+
+
+int
+qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
+ int *type,
+ virTypedParameterPtr *params,
+ int *nparams)
+{
+ switch (jobInfo->statsType) {
+ case QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION:
+ case QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP:
+ return qemuDomainMigrationJobInfoToParams(jobInfo, type, params, nparams);
+
+ case QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP:
+ return qemuDomainDumpJobInfoToParams(jobInfo, type, params, nparams);
+
+ case QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP:
+ return qemuDomainBackupJobInfoToParams(jobInfo, type, params, nparams);
+
+ case QEMU_DOMAIN_JOB_STATS_TYPE_NONE:
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("invalid job statistics type"));
+ break;
+
+ default:
+ virReportEnumRangeError(qemuDomainJobStatsType, jobInfo->statsType);
+ break;
+ }
+
+ return -1;
+}
+
+
+void
+qemuDomainJobInfoFree(qemuDomainJobInfoPtr info)
+{
+ g_free(info->errmsg);
+ g_free(info);
+}
+
+
+qemuDomainJobInfoPtr
+qemuDomainJobInfoCopy(qemuDomainJobInfoPtr info)
+{
+ qemuDomainJobInfoPtr ret = g_new0(qemuDomainJobInfo, 1);
+
+ memcpy(ret, info, sizeof(*info));
+
+ ret->errmsg = g_strdup(info->errmsg);
+
+ return ret;
+}
+
+
static void *
qemuJobAllocPrivate(void)
{
@@ -105,6 +556,8 @@ qemuJobFreePrivate(void *opaque)
return;
qemuMigrationParamsFree(priv->migParams);
+ g_clear_pointer(&priv->current, qemuDomainJobInfoFree);
+ g_clear_pointer(&priv->completed, qemuDomainJobInfoFree);
VIR_FREE(priv);
}
@@ -118,6 +571,7 @@ qemuJobResetPrivate(void *opaque)
priv->spiceMigrated = false;
priv->dumpCompleted = false;
qemuMigrationParamsFree(priv->migParams);
+ g_clear_pointer(&priv->current, qemuDomainJobInfoFree);
priv->migParams = NULL;
}
@@ -134,6 +588,48 @@ qemuDomainFormatJobPrivate(virBufferPtr buf,
return 0;
}
+void
+qemuDomainCurrentJobInfoInit(qemuDomainJobObjPtr job,
+ unsigned long long now)
+{
+ qemuDomainJobPrivatePtr priv = job->privateData;
+ priv->current = g_new0(qemuDomainJobInfo, 1);
+ priv->current->status = QEMU_DOMAIN_JOB_STATUS_ACTIVE;
+ priv->current->started = now;
+
+}
+
+void
+qemuDomainJobInfoSetOperation(qemuDomainJobObjPtr job,
+ virDomainJobOperation operation)
+{
+ qemuDomainJobPrivatePtr priv = job->privateData;
+ priv->current->operation = operation;
+}
+
+void
+qemuDomainEventEmitJobCompleted(virQEMUDriverPtr driver,
+ virDomainObjPtr vm)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
+ virObjectEventPtr event;
+ virTypedParameterPtr params = NULL;
+ int nparams = 0;
+ int type;
+
+ if (!jobPriv->completed)
+ return;
+
+ if (qemuDomainJobInfoToParams(jobPriv->completed, &type,
+ ¶ms, &nparams) < 0) {
+ VIR_WARN("Could not get stats for completed job; domain %s",
+ vm->def->name);
+ }
+
+ event = virDomainEventJobCompletedNewFromObj(vm, params, nparams);
+ virObjectEventStateQueue(driver->domainEventState, event);
+}
static int
qemuDomainParseJobPrivate(xmlXPathContextPtr ctxt,
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 29849a7313..90b2f7195a 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -492,6 +492,37 @@ struct _qemuDomainXmlNsDef {
char **capsdel;
};
+typedef struct _qemuDomainJobInfo qemuDomainJobInfo;
+typedef qemuDomainJobInfo *qemuDomainJobInfoPtr;
+struct _qemuDomainJobInfo {
+ qemuDomainJobStatus status;
+ virDomainJobOperation operation;
+ unsigned long long started; /* When the async job started */
+ unsigned long long stopped; /* When the domain's CPUs were stopped */
+ unsigned long long sent; /* When the source sent status info to the
+ destination (only for migrations). */
+ unsigned long long received; /* When the destination host received status
+ info from the source (migrations only). */
+ /* Computed values */
+ unsigned long long timeElapsed;
+ long long timeDelta; /* delta = received - sent, i.e., the difference
+ between the source and the destination time plus
+ the time between the end of Perform phase on the
+ source and the beginning of Finish phase on the
+ destination. */
+ bool timeDeltaSet;
+ /* Raw values from QEMU */
+ qemuDomainJobStatsType statsType;
+ union {
+ qemuMonitorMigrationStats mig;
+ qemuMonitorDumpStats dump;
+ qemuDomainBackupStats backup;
+ } stats;
+ qemuDomainMirrorStats mirrorStats;
+
+ char *errmsg; /* optional error message for failed completed jobs */
+};
+
typedef struct _qemuDomainJobPrivate qemuDomainJobPrivate;
typedef qemuDomainJobPrivate *qemuDomainJobPrivatePtr;
struct _qemuDomainJobPrivate {
@@ -500,8 +531,44 @@ struct _qemuDomainJobPrivate {
bool spiceMigrated; /* spice migration completed */
bool dumpCompleted; /* dump completed */
qemuMigrationParamsPtr migParams;
+ qemuDomainJobInfoPtr current; /* async job progress data */
+ qemuDomainJobInfoPtr completed; /* statistics data of a recently completed job */
};
+
+void qemuDomainEventEmitJobCompleted(virQEMUDriverPtr driver,
+ virDomainObjPtr vm);
+
+void
+qemuDomainJobInfoFree(qemuDomainJobInfoPtr info);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuDomainJobInfo, qemuDomainJobInfoFree);
+
+qemuDomainJobInfoPtr
+qemuDomainJobInfoCopy(qemuDomainJobInfoPtr info);
+
+void
+qemuDomainCurrentJobInfoInit(qemuDomainJobObjPtr job,
+ unsigned long long now);
+
+void
+qemuDomainJobInfoSetOperation(qemuDomainJobObjPtr job,
+ virDomainJobOperation operation);
+
+int qemuDomainJobInfoUpdateTime(qemuDomainJobInfoPtr jobInfo)
+ ATTRIBUTE_NONNULL(1);
+int qemuDomainJobInfoUpdateDowntime(qemuDomainJobInfoPtr jobInfo)
+ ATTRIBUTE_NONNULL(1);
+int qemuDomainJobInfoToInfo(qemuDomainJobInfoPtr jobInfo,
+ virDomainJobInfoPtr info)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+int qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
+ int *type,
+ virTypedParameterPtr *params,
+ int *nparams)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
+ ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
+
int qemuDomainObjStartWorker(virDomainObjPtr dom);
void qemuDomainObjStopWorker(virDomainObjPtr dom);
diff --git a/src/qemu/qemu_domainjob.c b/src/qemu/qemu_domainjob.c
index 6393cc0b40..1e120cc219 100644
--- a/src/qemu/qemu_domainjob.c
+++ b/src/qemu/qemu_domainjob.c
@@ -115,51 +115,6 @@ qemuDomainAsyncJobPhaseFromString(qemuDomainAsyncJob job,
return -1;
}
-
-void
-qemuDomainJobInfoFree(qemuDomainJobInfoPtr info)
-{
- g_free(info->errmsg);
- g_free(info);
-}
-
-
-qemuDomainJobInfoPtr
-qemuDomainJobInfoCopy(qemuDomainJobInfoPtr info)
-{
- qemuDomainJobInfoPtr ret = g_new0(qemuDomainJobInfo, 1);
-
- memcpy(ret, info, sizeof(*info));
-
- ret->errmsg = g_strdup(info->errmsg);
-
- return ret;
-}
-
-void
-qemuDomainEventEmitJobCompleted(virQEMUDriverPtr driver,
- virDomainObjPtr vm)
-{
- qemuDomainObjPrivatePtr priv = vm->privateData;
- virObjectEventPtr event;
- virTypedParameterPtr params = NULL;
- int nparams = 0;
- int type;
-
- if (!priv->job.completed)
- return;
-
- if (qemuDomainJobInfoToParams(priv->job.completed, &type,
- ¶ms, &nparams) < 0) {
- VIR_WARN("Could not get stats for completed job; domain %s",
- vm->def->name);
- }
-
- event = virDomainEventJobCompletedNewFromObj(vm, params, nparams);
- virObjectEventStateQueue(driver->domainEventState, event);
-}
-
-
int
qemuDomainObjInitJob(qemuDomainJobObjPtr job,
qemuDomainObjPrivateJobCallbacksPtr cb)
@@ -216,7 +171,6 @@ qemuDomainObjResetAsyncJob(qemuDomainJobObjPtr job)
job->mask = QEMU_JOB_DEFAULT_MASK;
job->abortJob = false;
VIR_FREE(job->error);
- g_clear_pointer(&job->current, qemuDomainJobInfoFree);
job->cb->resetJobPrivate(job->privateData);
job->apiFlags = 0;
}
@@ -251,8 +205,6 @@ qemuDomainObjFreeJob(qemuDomainJobObjPtr job)
qemuDomainObjResetJob(job);
qemuDomainObjResetAsyncJob(job);
job->cb->freeJobPrivate(job->privateData);
- g_clear_pointer(&job->current, qemuDomainJobInfoFree);
- g_clear_pointer(&job->completed, qemuDomainJobInfoFree);
virCondDestroy(&job->cond);
virCondDestroy(&job->asyncCond);
}
@@ -264,435 +216,6 @@ qemuDomainTrackJob(qemuDomainJob job)
}
-int
-qemuDomainJobInfoUpdateTime(qemuDomainJobInfoPtr jobInfo)
-{
- unsigned long long now;
-
- if (!jobInfo->started)
- return 0;
-
- if (virTimeMillisNow(&now) < 0)
- return -1;
-
- if (now < jobInfo->started) {
- VIR_WARN("Async job starts in the future");
- jobInfo->started = 0;
- return 0;
- }
-
- jobInfo->timeElapsed = now - jobInfo->started;
- return 0;
-}
-
-int
-qemuDomainJobInfoUpdateDowntime(qemuDomainJobInfoPtr jobInfo)
-{
- unsigned long long now;
-
- if (!jobInfo->stopped)
- return 0;
-
- if (virTimeMillisNow(&now) < 0)
- return -1;
-
- if (now < jobInfo->stopped) {
- VIR_WARN("Guest's CPUs stopped in the future");
- jobInfo->stopped = 0;
- return 0;
- }
-
- jobInfo->stats.mig.downtime = now - jobInfo->stopped;
- jobInfo->stats.mig.downtime_set = true;
- return 0;
-}
-
-static virDomainJobType
-qemuDomainJobStatusToType(qemuDomainJobStatus status)
-{
- switch (status) {
- case QEMU_DOMAIN_JOB_STATUS_NONE:
- break;
-
- case QEMU_DOMAIN_JOB_STATUS_ACTIVE:
- case QEMU_DOMAIN_JOB_STATUS_MIGRATING:
- case QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED:
- case QEMU_DOMAIN_JOB_STATUS_POSTCOPY:
- case QEMU_DOMAIN_JOB_STATUS_PAUSED:
- return VIR_DOMAIN_JOB_UNBOUNDED;
-
- case QEMU_DOMAIN_JOB_STATUS_COMPLETED:
- return VIR_DOMAIN_JOB_COMPLETED;
-
- case QEMU_DOMAIN_JOB_STATUS_FAILED:
- return VIR_DOMAIN_JOB_FAILED;
-
- case QEMU_DOMAIN_JOB_STATUS_CANCELED:
- return VIR_DOMAIN_JOB_CANCELLED;
- }
-
- return VIR_DOMAIN_JOB_NONE;
-}
-
-int
-qemuDomainJobInfoToInfo(qemuDomainJobInfoPtr jobInfo,
- virDomainJobInfoPtr info)
-{
- info->type = qemuDomainJobStatusToType(jobInfo->status);
- info->timeElapsed = jobInfo->timeElapsed;
-
- switch (jobInfo->statsType) {
- case QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION:
- info->memTotal = jobInfo->stats.mig.ram_total;
- info->memRemaining = jobInfo->stats.mig.ram_remaining;
- info->memProcessed = jobInfo->stats.mig.ram_transferred;
- info->fileTotal = jobInfo->stats.mig.disk_total +
- jobInfo->mirrorStats.total;
- info->fileRemaining = jobInfo->stats.mig.disk_remaining +
- (jobInfo->mirrorStats.total -
- jobInfo->mirrorStats.transferred);
- info->fileProcessed = jobInfo->stats.mig.disk_transferred +
- jobInfo->mirrorStats.transferred;
- break;
-
- case QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP:
- info->memTotal = jobInfo->stats.mig.ram_total;
- info->memRemaining = jobInfo->stats.mig.ram_remaining;
- info->memProcessed = jobInfo->stats.mig.ram_transferred;
- break;
-
- case QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP:
- info->memTotal = jobInfo->stats.dump.total;
- info->memProcessed = jobInfo->stats.dump.completed;
- info->memRemaining = info->memTotal - info->memProcessed;
- break;
-
- case QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP:
- info->fileTotal = jobInfo->stats.backup.total;
- info->fileProcessed = jobInfo->stats.backup.transferred;
- info->fileRemaining = info->fileTotal - info->fileProcessed;
- break;
-
- case QEMU_DOMAIN_JOB_STATS_TYPE_NONE:
- break;
- }
-
- info->dataTotal = info->memTotal + info->fileTotal;
- info->dataRemaining = info->memRemaining + info->fileRemaining;
- info->dataProcessed = info->memProcessed + info->fileProcessed;
-
- return 0;
-}
-
-
-static int
-qemuDomainMigrationJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
- int *type,
- virTypedParameterPtr *params,
- int *nparams)
-{
- qemuMonitorMigrationStats *stats = &jobInfo->stats.mig;
- qemuDomainMirrorStatsPtr mirrorStats = &jobInfo->mirrorStats;
- virTypedParameterPtr par = NULL;
- int maxpar = 0;
- int npar = 0;
- unsigned long long mirrorRemaining = mirrorStats->total -
- mirrorStats->transferred;
-
- if (virTypedParamsAddInt(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_OPERATION,
- jobInfo->operation) < 0)
- goto error;
-
- if (virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_TIME_ELAPSED,
- jobInfo->timeElapsed) < 0)
- goto error;
-
- if (jobInfo->timeDeltaSet &&
- jobInfo->timeElapsed > jobInfo->timeDelta &&
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_TIME_ELAPSED_NET,
- jobInfo->timeElapsed - jobInfo->timeDelta) < 0)
- goto error;
-
- if (stats->downtime_set &&
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_DOWNTIME,
- stats->downtime) < 0)
- goto error;
-
- if (stats->downtime_set &&
- jobInfo->timeDeltaSet &&
- stats->downtime > jobInfo->timeDelta &&
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_DOWNTIME_NET,
- stats->downtime - jobInfo->timeDelta) < 0)
- goto error;
-
- if (stats->setup_time_set &&
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_SETUP_TIME,
- stats->setup_time) < 0)
- goto error;
-
- if (virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_DATA_TOTAL,
- stats->ram_total +
- stats->disk_total +
- mirrorStats->total) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_DATA_PROCESSED,
- stats->ram_transferred +
- stats->disk_transferred +
- mirrorStats->transferred) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_DATA_REMAINING,
- stats->ram_remaining +
- stats->disk_remaining +
- mirrorRemaining) < 0)
- goto error;
-
- if (virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_TOTAL,
- stats->ram_total) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_PROCESSED,
- stats->ram_transferred) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_REMAINING,
- stats->ram_remaining) < 0)
- goto error;
-
- if (stats->ram_bps &&
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_BPS,
- stats->ram_bps) < 0)
- goto error;
-
- if (stats->ram_duplicate_set) {
- if (virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_CONSTANT,
- stats->ram_duplicate) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_NORMAL,
- stats->ram_normal) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_NORMAL_BYTES,
- stats->ram_normal_bytes) < 0)
- goto error;
- }
-
- if (virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_DIRTY_RATE,
- stats->ram_dirty_rate) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_ITERATION,
- stats->ram_iteration) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_POSTCOPY_REQS,
- stats->ram_postcopy_reqs) < 0)
- goto error;
-
- if (stats->ram_page_size > 0 &&
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_PAGE_SIZE,
- stats->ram_page_size) < 0)
- goto error;
-
- /* The remaining stats are disk, mirror, or migration specific
- * so if this is a SAVEDUMP, we can just skip them */
- if (jobInfo->statsType == QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP)
- goto done;
-
- if (virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_DISK_TOTAL,
- stats->disk_total +
- mirrorStats->total) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_DISK_PROCESSED,
- stats->disk_transferred +
- mirrorStats->transferred) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_DISK_REMAINING,
- stats->disk_remaining +
- mirrorRemaining) < 0)
- goto error;
-
- if (stats->disk_bps &&
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_DISK_BPS,
- stats->disk_bps) < 0)
- goto error;
-
- if (stats->xbzrle_set) {
- if (virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_COMPRESSION_CACHE,
- stats->xbzrle_cache_size) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_COMPRESSION_BYTES,
- stats->xbzrle_bytes) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_COMPRESSION_PAGES,
- stats->xbzrle_pages) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_COMPRESSION_CACHE_MISSES,
- stats->xbzrle_cache_miss) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_COMPRESSION_OVERFLOW,
- stats->xbzrle_overflow) < 0)
- goto error;
- }
-
- if (stats->cpu_throttle_percentage &&
- virTypedParamsAddInt(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_AUTO_CONVERGE_THROTTLE,
- stats->cpu_throttle_percentage) < 0)
- goto error;
-
- done:
- *type = qemuDomainJobStatusToType(jobInfo->status);
- *params = par;
- *nparams = npar;
- return 0;
-
- error:
- virTypedParamsFree(par, npar);
- return -1;
-}
-
-
-static int
-qemuDomainDumpJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
- int *type,
- virTypedParameterPtr *params,
- int *nparams)
-{
- qemuMonitorDumpStats *stats = &jobInfo->stats.dump;
- virTypedParameterPtr par = NULL;
- int maxpar = 0;
- int npar = 0;
-
- if (virTypedParamsAddInt(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_OPERATION,
- jobInfo->operation) < 0)
- goto error;
-
- if (virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_TIME_ELAPSED,
- jobInfo->timeElapsed) < 0)
- goto error;
-
- if (virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_TOTAL,
- stats->total) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_PROCESSED,
- stats->completed) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_REMAINING,
- stats->total - stats->completed) < 0)
- goto error;
-
- *type = qemuDomainJobStatusToType(jobInfo->status);
- *params = par;
- *nparams = npar;
- return 0;
-
- error:
- virTypedParamsFree(par, npar);
- return -1;
-}
-
-
-static int
-qemuDomainBackupJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
- int *type,
- virTypedParameterPtr *params,
- int *nparams)
-{
- qemuDomainBackupStats *stats = &jobInfo->stats.backup;
- g_autoptr(virTypedParamList) par = g_new0(virTypedParamList, 1);
-
- if (virTypedParamListAddInt(par, jobInfo->operation,
- VIR_DOMAIN_JOB_OPERATION) < 0)
- return -1;
-
- if (virTypedParamListAddULLong(par, jobInfo->timeElapsed,
- VIR_DOMAIN_JOB_TIME_ELAPSED) < 0)
- return -1;
-
- if (stats->transferred > 0 || stats->total > 0) {
- if (virTypedParamListAddULLong(par, stats->total,
- VIR_DOMAIN_JOB_DISK_TOTAL) < 0)
- return -1;
-
- if (virTypedParamListAddULLong(par, stats->transferred,
- VIR_DOMAIN_JOB_DISK_PROCESSED) < 0)
- return -1;
-
- if (virTypedParamListAddULLong(par, stats->total - stats->transferred,
- VIR_DOMAIN_JOB_DISK_REMAINING) < 0)
- return -1;
- }
-
- if (stats->tmp_used > 0 || stats->tmp_total > 0) {
- if (virTypedParamListAddULLong(par, stats->tmp_used,
- VIR_DOMAIN_JOB_DISK_TEMP_USED) < 0)
- return -1;
-
- if (virTypedParamListAddULLong(par, stats->tmp_total,
- VIR_DOMAIN_JOB_DISK_TEMP_TOTAL) < 0)
- return -1;
- }
-
- if (jobInfo->status != QEMU_DOMAIN_JOB_STATUS_ACTIVE &&
- virTypedParamListAddBoolean(par,
- jobInfo->status == QEMU_DOMAIN_JOB_STATUS_COMPLETED,
- VIR_DOMAIN_JOB_SUCCESS) < 0)
- return -1;
-
- if (jobInfo->errmsg &&
- virTypedParamListAddString(par, jobInfo->errmsg, VIR_DOMAIN_JOB_ERRMSG) < 0)
- return -1;
-
- *nparams = virTypedParamListStealParams(par, params);
- *type = qemuDomainJobStatusToType(jobInfo->status);
- return 0;
-}
-
-
-int
-qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
- int *type,
- virTypedParameterPtr *params,
- int *nparams)
-{
- switch (jobInfo->statsType) {
- case QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION:
- case QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP:
- return qemuDomainMigrationJobInfoToParams(jobInfo, type, params, nparams);
-
- case QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP:
- return qemuDomainDumpJobInfoToParams(jobInfo, type, params, nparams);
-
- case QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP:
- return qemuDomainBackupJobInfoToParams(jobInfo, type, params, nparams);
-
- case QEMU_DOMAIN_JOB_STATS_TYPE_NONE:
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("invalid job statistics type"));
- break;
-
- default:
- virReportEnumRangeError(qemuDomainJobStatsType, jobInfo->statsType);
- break;
- }
-
- return -1;
-}
-
-
void
qemuDomainObjSetJobPhase(virQEMUDriverPtr driver,
virDomainObjPtr obj,
@@ -894,13 +417,11 @@ qemuDomainObjBeginJobInternal(virQEMUDriverPtr driver,
qemuDomainAsyncJobTypeToString(asyncJob),
obj, obj->def->name);
qemuDomainObjResetAsyncJob(&priv->job);
- priv->job.current = g_new0(qemuDomainJobInfo, 1);
- priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_ACTIVE;
+ qemuDomainCurrentJobInfoInit(&priv->job, now);
priv->job.asyncJob = asyncJob;
priv->job.asyncOwner = virThreadSelfID();
priv->job.asyncOwnerAPI = virThreadJobGet();
priv->job.asyncStarted = now;
- priv->job.current->started = now;
}
}
@@ -1066,7 +587,7 @@ int qemuDomainObjBeginAsyncJob(virQEMUDriverPtr driver,
return -1;
priv = obj->privateData;
- priv->job.current->operation = operation;
+ qemuDomainJobInfoSetOperation(&priv->job, operation);
priv->job.apiFlags = apiFlags;
return 0;
}
diff --git a/src/qemu/qemu_domainjob.h b/src/qemu/qemu_domainjob.h
index c83e055647..f658a1f1d1 100644
--- a/src/qemu/qemu_domainjob.h
+++ b/src/qemu/qemu_domainjob.h
@@ -115,45 +115,6 @@ struct _qemuDomainBackupStats {
unsigned long long tmp_total;
};
-typedef struct _qemuDomainJobInfo qemuDomainJobInfo;
-typedef qemuDomainJobInfo *qemuDomainJobInfoPtr;
-struct _qemuDomainJobInfo {
- qemuDomainJobStatus status;
- virDomainJobOperation operation;
- unsigned long long started; /* When the async job started */
- unsigned long long stopped; /* When the domain's CPUs were stopped */
- unsigned long long sent; /* When the source sent status info to the
- destination (only for migrations). */
- unsigned long long received; /* When the destination host received status
- info from the source (migrations only). */
- /* Computed values */
- unsigned long long timeElapsed;
- long long timeDelta; /* delta = received - sent, i.e., the difference
- between the source and the destination time plus
- the time between the end of Perform phase on the
- source and the beginning of Finish phase on the
- destination. */
- bool timeDeltaSet;
- /* Raw values from QEMU */
- qemuDomainJobStatsType statsType;
- union {
- qemuMonitorMigrationStats mig;
- qemuMonitorDumpStats dump;
- qemuDomainBackupStats backup;
- } stats;
- qemuDomainMirrorStats mirrorStats;
-
- char *errmsg; /* optional error message for failed completed jobs */
-};
-
-void
-qemuDomainJobInfoFree(qemuDomainJobInfoPtr info);
-
-G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuDomainJobInfo, qemuDomainJobInfoFree);
-
-qemuDomainJobInfoPtr
-qemuDomainJobInfoCopy(qemuDomainJobInfoPtr info);
-
typedef struct _qemuDomainJobObj qemuDomainJobObj;
typedef qemuDomainJobObj *qemuDomainJobObjPtr;
@@ -198,8 +159,6 @@ struct _qemuDomainJobObj {
unsigned long long asyncStarted; /* When the current async job started */
int phase; /* Job phase (mainly for migrations) */
unsigned long long mask; /* Jobs allowed during async job */
- qemuDomainJobInfoPtr current; /* async job progress data */
- qemuDomainJobInfoPtr completed; /* statistics data of a recently completed job */
bool abortJob; /* abort of the job requested */
char *error; /* job event completion error */
unsigned long apiFlags; /* flags passed to the API which started the async job */
@@ -213,9 +172,6 @@ const char *qemuDomainAsyncJobPhaseToString(qemuDomainAsyncJob job,
int qemuDomainAsyncJobPhaseFromString(qemuDomainAsyncJob job,
const char *phase);
-void qemuDomainEventEmitJobCompleted(virQEMUDriverPtr driver,
- virDomainObjPtr vm);
-
int qemuDomainObjBeginJob(virQEMUDriverPtr driver,
virDomainObjPtr obj,
qemuDomainJob job)
@@ -262,20 +218,6 @@ void qemuDomainRemoveInactiveJob(virQEMUDriverPtr driver,
void qemuDomainRemoveInactiveJobLocked(virQEMUDriverPtr driver,
virDomainObjPtr vm);
-int qemuDomainJobInfoUpdateTime(qemuDomainJobInfoPtr jobInfo)
- ATTRIBUTE_NONNULL(1);
-int qemuDomainJobInfoUpdateDowntime(qemuDomainJobInfoPtr jobInfo)
- ATTRIBUTE_NONNULL(1);
-int qemuDomainJobInfoToInfo(qemuDomainJobInfoPtr jobInfo,
- virDomainJobInfoPtr info)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
-int qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
- int *type,
- virTypedParameterPtr *params,
- int *nparams)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
- ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
-
bool qemuDomainTrackJob(qemuDomainJob job);
void qemuDomainObjFreeJob(qemuDomainJobObjPtr job);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 53980d4d78..6b0f84bf78 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2723,6 +2723,7 @@ qemuDomainGetControlInfo(virDomainPtr dom,
{
virDomainObjPtr vm;
qemuDomainObjPrivatePtr priv;
+ qemuDomainJobPrivatePtr jobPriv;
int ret = -1;
virCheckFlags(0, -1);
@@ -2737,6 +2738,7 @@ qemuDomainGetControlInfo(virDomainPtr dom,
goto cleanup;
priv = vm->privateData;
+ jobPriv = priv->job.privateData;
memset(info, 0, sizeof(*info));
@@ -2746,9 +2748,9 @@ qemuDomainGetControlInfo(virDomainPtr dom,
} else if (priv->job.active) {
if (virTimeMillisNow(&info->stateTime) < 0)
goto cleanup;
- if (priv->job.current) {
+ if (jobPriv->current) {
info->state = VIR_DOMAIN_CONTROL_JOB;
- info->stateTime -= priv->job.current->started;
+ info->stateTime -= jobPriv->current->started;
} else {
if (priv->monStart > 0) {
info->state = VIR_DOMAIN_CONTROL_OCCUPIED;
@@ -3313,6 +3315,7 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver,
int ret = -1;
virObjectEventPtr event = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
virQEMUSaveDataPtr data = NULL;
g_autoptr(qemuDomainSaveCookie) cookie = NULL;
@@ -3329,7 +3332,7 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver,
goto endjob;
}
- priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP;
+ jobPriv->current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP;
/* Pause */
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
@@ -3716,7 +3719,7 @@ qemuDumpWaitForCompletion(virDomainObjPtr vm)
return -1;
}
- if (priv->job.current->stats.dump.status == QEMU_MONITOR_DUMP_STATUS_FAILED) {
+ if (jobPriv->current->stats.dump.status == QEMU_MONITOR_DUMP_STATUS_FAILED) {
if (priv->job.error)
virReportError(VIR_ERR_OPERATION_FAILED,
_("memory-only dump failed: %s"),
@@ -3727,7 +3730,7 @@ qemuDumpWaitForCompletion(virDomainObjPtr vm)
return -1;
}
- qemuDomainJobInfoUpdateTime(priv->job.current);
+ qemuDomainJobInfoUpdateTime(jobPriv->current);
return 0;
}
@@ -3741,6 +3744,7 @@ qemuDumpToFd(virQEMUDriverPtr driver,
const char *dumpformat)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
bool detach = false;
int ret = -1;
@@ -3756,9 +3760,9 @@ qemuDumpToFd(virQEMUDriverPtr driver,
return -1;
if (detach)
- priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP;
+ jobPriv->current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP;
else
- g_clear_pointer(&priv->job.current, qemuDomainJobInfoFree);
+ g_clear_pointer(&jobPriv->current, qemuDomainJobInfoFree);
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
return -1;
@@ -3895,6 +3899,7 @@ qemuDomainCoreDumpWithFormat(virDomainPtr dom,
virQEMUDriverPtr driver = dom->conn->privateData;
virDomainObjPtr vm;
qemuDomainObjPrivatePtr priv = NULL;
+ qemuDomainJobPrivatePtr jobPriv;
bool resume = false, paused = false;
int ret = -1;
virObjectEventPtr event = NULL;
@@ -3919,7 +3924,8 @@ qemuDomainCoreDumpWithFormat(virDomainPtr dom,
goto endjob;
priv = vm->privateData;
- priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP;
+ jobPriv = priv->job.privateData;
+ jobPriv->current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP;
/* Migrate will always stop the VM, so the resume condition is
independent of whether the stop command is issued. */
@@ -7481,6 +7487,7 @@ qemuDomainObjStart(virConnectPtr conn,
bool force_boot = (flags & VIR_DOMAIN_START_FORCE_BOOT) != 0;
unsigned int start_flags = VIR_QEMU_PROCESS_START_COLD;
qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
start_flags |= start_paused ? VIR_QEMU_PROCESS_START_PAUSED : 0;
start_flags |= autodestroy ? VIR_QEMU_PROCESS_START_AUTODESTROY : 0;
@@ -7504,8 +7511,8 @@ qemuDomainObjStart(virConnectPtr conn,
}
vm->hasManagedSave = false;
} else {
- virDomainJobOperation op = priv->job.current->operation;
- priv->job.current->operation = VIR_DOMAIN_JOB_OPERATION_RESTORE;
+ virDomainJobOperation op = jobPriv->current->operation;
+ jobPriv->current->operation = VIR_DOMAIN_JOB_OPERATION_RESTORE;
ret = qemuDomainObjRestore(conn, driver, vm, managed_save,
start_paused, bypass_cache, asyncJob);
@@ -7523,7 +7530,7 @@ qemuDomainObjStart(virConnectPtr conn,
return ret;
} else {
VIR_WARN("Ignoring incomplete managed state %s", managed_save);
- priv->job.current->operation = op;
+ jobPriv->current->operation = op;
vm->hasManagedSave = false;
}
}
@@ -13577,13 +13584,14 @@ qemuDomainGetJobStatsInternal(virQEMUDriverPtr driver,
qemuDomainJobInfoPtr *jobInfo)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
int ret = -1;
*jobInfo = NULL;
if (completed) {
- if (priv->job.completed && !priv->job.current)
- *jobInfo = qemuDomainJobInfoCopy(priv->job.completed);
+ if (jobPriv->completed && !jobPriv->current)
+ *jobInfo = qemuDomainJobInfoCopy(jobPriv->completed);
return 0;
}
@@ -13601,11 +13609,11 @@ qemuDomainGetJobStatsInternal(virQEMUDriverPtr driver,
if (virDomainObjCheckActive(vm) < 0)
goto cleanup;
- if (!priv->job.current) {
+ if (!jobPriv->current) {
ret = 0;
goto cleanup;
}
- *jobInfo = qemuDomainJobInfoCopy(priv->job.current);
+ *jobInfo = qemuDomainJobInfoCopy(jobPriv->current);
switch ((*jobInfo)->statsType) {
case QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION:
@@ -13680,6 +13688,7 @@ qemuDomainGetJobStats(virDomainPtr dom,
virQEMUDriverPtr driver = dom->conn->privateData;
virDomainObjPtr vm;
qemuDomainObjPrivatePtr priv;
+ qemuDomainJobPrivatePtr jobPriv;
g_autoptr(qemuDomainJobInfo) jobInfo = NULL;
bool completed = !!(flags & VIR_DOMAIN_JOB_STATS_COMPLETED);
int ret = -1;
@@ -13694,6 +13703,7 @@ qemuDomainGetJobStats(virDomainPtr dom,
goto cleanup;
priv = vm->privateData;
+ jobPriv = priv->job.privateData;
if (qemuDomainGetJobStatsInternal(driver, vm, completed, &jobInfo) < 0)
goto cleanup;
@@ -13709,7 +13719,7 @@ qemuDomainGetJobStats(virDomainPtr dom,
ret = qemuDomainJobInfoToParams(jobInfo, type, params, nparams);
if (completed && ret == 0 && !(flags & VIR_DOMAIN_JOB_STATS_KEEP_COMPLETED))
- g_clear_pointer(&priv->job.completed, qemuDomainJobInfoFree);
+ g_clear_pointer(&jobPriv->completed, qemuDomainJobInfoFree);
cleanup:
virDomainObjEndAPI(&vm);
@@ -13741,6 +13751,7 @@ static int qemuDomainAbortJob(virDomainPtr dom)
virDomainObjPtr vm;
int ret = -1;
qemuDomainObjPrivatePtr priv;
+ qemuDomainJobPrivatePtr jobPriv;
int reason;
if (!(vm = qemuDomainObjFromDomain(dom)))
@@ -13756,6 +13767,7 @@ static int qemuDomainAbortJob(virDomainPtr dom)
goto endjob;
priv = vm->privateData;
+ jobPriv = priv->job.privateData;
switch (priv->job.asyncJob) {
case QEMU_ASYNC_JOB_NONE:
@@ -13776,7 +13788,7 @@ static int qemuDomainAbortJob(virDomainPtr dom)
break;
case QEMU_ASYNC_JOB_MIGRATION_OUT:
- if ((priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY ||
+ if ((jobPriv->current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY ||
(virDomainObjGetState(vm, &reason) == VIR_DOMAIN_PAUSED &&
reason == VIR_DOMAIN_PAUSED_POSTCOPY))) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
@@ -15448,6 +15460,7 @@ qemuDomainSnapshotCreateActiveExternal(virQEMUDriverPtr driver,
bool resume = false;
int ret = -1;
qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
g_autofree char *xml = NULL;
virDomainSnapshotDefPtr snapdef = virDomainSnapshotObjGetDef(snap);
bool memory = snapdef->memory == VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL;
@@ -15517,7 +15530,7 @@ qemuDomainSnapshotCreateActiveExternal(virQEMUDriverPtr driver,
if (!qemuMigrationSrcIsAllowed(driver, vm, false, 0))
goto cleanup;
- priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP;
+ jobPriv->current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP;
/* allow the migration job to be cancelled or the domain to be paused */
qemuDomainObjSetAsyncJobMask(vm, (QEMU_JOB_DEFAULT_MASK |
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 2c7bf349c3..b8bb02435f 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1008,6 +1008,7 @@ qemuMigrationSrcNBDStorageCopy(virQEMUDriverPtr driver,
unsigned int flags)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
int port;
size_t i;
unsigned long long mirror_speed = speed;
@@ -1052,7 +1053,7 @@ qemuMigrationSrcNBDStorageCopy(virQEMUDriverPtr driver,
return -1;
if (priv->job.abortJob) {
- priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_CANCELED;
+ jobPriv->current->status = QEMU_DOMAIN_JOB_STATUS_CANCELED;
virReportError(VIR_ERR_OPERATION_ABORTED, _("%s: %s"),
qemuDomainAsyncJobTypeToString(priv->job.asyncJob),
_("canceled by client"));
@@ -1070,7 +1071,7 @@ qemuMigrationSrcNBDStorageCopy(virQEMUDriverPtr driver,
}
qemuMigrationSrcFetchMirrorStats(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT,
- priv->job.current);
+ jobPriv->current);
/* Okay, all disks are ready. Modify migrate_flags */
*migrate_flags &= ~(QEMU_MONITOR_MIGRATE_NON_SHARED_DISK |
@@ -1538,7 +1539,8 @@ qemuMigrationJobCheckStatus(virQEMUDriverPtr driver,
qemuDomainAsyncJob asyncJob)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
- qemuDomainJobInfoPtr jobInfo = priv->job.current;
+ qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
+ qemuDomainJobInfoPtr jobInfo = jobPriv->current;
char *error = NULL;
bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
int ret = -1;
@@ -1608,7 +1610,8 @@ qemuMigrationAnyCompleted(virQEMUDriverPtr driver,
unsigned int flags)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
- qemuDomainJobInfoPtr jobInfo = priv->job.current;
+ qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
+ qemuDomainJobInfoPtr jobInfo = jobPriv->current;
int pauseReason;
if (qemuMigrationJobCheckStatus(driver, vm, asyncJob) < 0)
@@ -1699,7 +1702,8 @@ qemuMigrationSrcWaitForCompletion(virQEMUDriverPtr driver,
unsigned int flags)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
- qemuDomainJobInfoPtr jobInfo = priv->job.current;
+ qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
+ qemuDomainJobInfoPtr jobInfo = jobPriv->current;
bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
int rv;
@@ -1731,9 +1735,9 @@ qemuMigrationSrcWaitForCompletion(virQEMUDriverPtr driver,
qemuDomainJobInfoUpdateTime(jobInfo);
qemuDomainJobInfoUpdateDowntime(jobInfo);
- g_clear_pointer(&priv->job.completed, qemuDomainJobInfoFree);
- priv->job.completed = qemuDomainJobInfoCopy(jobInfo);
- priv->job.completed->status = QEMU_DOMAIN_JOB_STATUS_COMPLETED;
+ g_clear_pointer(&jobPriv->completed, qemuDomainJobInfoFree);
+ jobPriv->completed = qemuDomainJobInfoCopy(jobInfo);
+ jobPriv->completed->status = QEMU_DOMAIN_JOB_STATUS_COMPLETED;
if (asyncJob != QEMU_ASYNC_JOB_MIGRATION_OUT &&
jobInfo->status == QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED)
@@ -3006,16 +3010,16 @@ qemuMigrationSrcConfirmPhase(virQEMUDriverPtr driver,
return -1;
if (retcode == 0)
- jobInfo = priv->job.completed;
+ jobInfo = jobPriv->completed;
else
- g_clear_pointer(&priv->job.completed, qemuDomainJobInfoFree);
+ g_clear_pointer(&jobPriv->completed, qemuDomainJobInfoFree);
/* Update times with the values sent by the destination daemon */
if (mig->jobInfo && jobInfo) {
int reason;
/* We need to refresh migration statistics after a completed post-copy
- * migration since priv->job.completed contains obsolete data from the
+ * migration since jobPriv->completed contains obsolete data from the
* time we switched to post-copy mode.
*/
if (virDomainObjGetState(vm, &reason) == VIR_DOMAIN_PAUSED &&
@@ -3467,6 +3471,7 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
int ret = -1;
unsigned int migrate_flags = QEMU_MONITOR_MIGRATE_BACKGROUND;
qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
g_autoptr(qemuMigrationCookie) mig = NULL;
g_autofree char *tlsAlias = NULL;
qemuMigrationIOThreadPtr iothread = NULL;
@@ -3624,7 +3629,7 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
/* explicitly do this *after* we entered the monitor,
* as this is a critical section so we are guaranteed
* priv->job.abortJob will not change */
- priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_CANCELED;
+ jobPriv->current->status = QEMU_DOMAIN_JOB_STATUS_CANCELED;
virReportError(VIR_ERR_OPERATION_ABORTED, _("%s: %s"),
qemuDomainAsyncJobTypeToString(priv->job.asyncJob),
_("canceled by client"));
@@ -3729,7 +3734,7 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
* resume it now once we finished all block jobs and wait for the real
* end of the migration.
*/
- if (priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_PAUSED) {
+ if (jobPriv->current->status == QEMU_DOMAIN_JOB_STATUS_PAUSED) {
if (qemuMigrationSrcContinue(driver, vm,
QEMU_MONITOR_MIGRATION_STATUS_PRE_SWITCHOVER,
QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
@@ -3757,11 +3762,11 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
goto error;
}
- if (priv->job.completed) {
- priv->job.completed->stopped = priv->job.current->stopped;
- qemuDomainJobInfoUpdateTime(priv->job.completed);
- qemuDomainJobInfoUpdateDowntime(priv->job.completed);
- ignore_value(virTimeMillisNow(&priv->job.completed->sent));
+ if (jobPriv->completed) {
+ jobPriv->completed->stopped = jobPriv->current->stopped;
+ qemuDomainJobInfoUpdateTime(jobPriv->completed);
+ qemuDomainJobInfoUpdateDowntime(jobPriv->completed);
+ ignore_value(virTimeMillisNow(&jobPriv->completed->sent));
}
cookieFlags |= QEMU_MIGRATION_COOKIE_NETWORK |
@@ -3789,7 +3794,7 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
if (virDomainObjIsActive(vm)) {
if (cancel &&
- priv->job.current->status != QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED &&
+ jobPriv->current->status != QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED &&
qemuDomainObjEnterMonitorAsync(driver, vm,
QEMU_ASYNC_JOB_MIGRATION_OUT) == 0) {
qemuMonitorMigrateCancel(priv->mon);
@@ -3802,8 +3807,8 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
QEMU_ASYNC_JOB_MIGRATION_OUT,
dconn);
- if (priv->job.current->status != QEMU_DOMAIN_JOB_STATUS_CANCELED)
- priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_FAILED;
+ if (jobPriv->current->status != QEMU_DOMAIN_JOB_STATUS_CANCELED)
+ jobPriv->current->status = QEMU_DOMAIN_JOB_STATUS_FAILED;
}
if (iothread)
@@ -5011,7 +5016,7 @@ qemuMigrationDstFinish(virQEMUDriverPtr driver,
: QEMU_MIGRATION_PHASE_FINISH2);
qemuDomainCleanupRemove(vm, qemuMigrationDstPrepareCleanup);
- g_clear_pointer(&priv->job.completed, qemuDomainJobInfoFree);
+ g_clear_pointer(&jobPriv->completed, qemuDomainJobInfoFree);
cookie_flags = QEMU_MIGRATION_COOKIE_NETWORK |
QEMU_MIGRATION_COOKIE_STATS |
@@ -5103,7 +5108,7 @@ qemuMigrationDstFinish(virQEMUDriverPtr driver,
goto endjob;
}
- if (priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY)
+ if (jobPriv->current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY)
inPostCopy = true;
if (!(flags & VIR_MIGRATE_PAUSED)) {
@@ -5217,9 +5222,9 @@ qemuMigrationDstFinish(virQEMUDriverPtr driver,
if (dom) {
if (jobInfo) {
- priv->job.completed = g_steal_pointer(&jobInfo);
- priv->job.completed->status = QEMU_DOMAIN_JOB_STATUS_COMPLETED;
- priv->job.completed->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION;
+ jobPriv->completed = g_steal_pointer(&jobInfo);
+ jobPriv->completed->status = QEMU_DOMAIN_JOB_STATUS_COMPLETED;
+ jobPriv->completed->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION;
}
if (qemuMigrationBakeCookie(mig, driver, vm,
@@ -5232,7 +5237,7 @@ qemuMigrationDstFinish(virQEMUDriverPtr driver,
* is obsolete anyway.
*/
if (inPostCopy)
- g_clear_pointer(&priv->job.completed, qemuDomainJobInfoFree);
+ g_clear_pointer(&jobPriv->completed, qemuDomainJobInfoFree);
}
qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN,
@@ -5461,6 +5466,7 @@ qemuMigrationJobStart(virQEMUDriverPtr driver,
unsigned long apiFlags)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
virDomainJobOperation op;
unsigned long long mask;
@@ -5477,7 +5483,7 @@ qemuMigrationJobStart(virQEMUDriverPtr driver,
if (qemuDomainObjBeginAsyncJob(driver, vm, job, op, apiFlags) < 0)
return -1;
- priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION;
+ jobPriv->current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION;
qemuDomainObjSetAsyncJobMask(vm, mask);
return 0;
diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c
index 81b557e0a8..a0e8cba8ba 100644
--- a/src/qemu/qemu_migration_cookie.c
+++ b/src/qemu/qemu_migration_cookie.c
@@ -509,12 +509,13 @@ qemuMigrationCookieAddStatistics(qemuMigrationCookiePtr mig,
virDomainObjPtr vm)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
- if (!priv->job.completed)
+ if (!jobPriv->completed)
return 0;
g_clear_pointer(&mig->jobInfo, qemuDomainJobInfoFree);
- mig->jobInfo = qemuDomainJobInfoCopy(priv->job.completed);
+ mig->jobInfo = qemuDomainJobInfoCopy(jobPriv->completed);
mig->flags |= QEMU_MIGRATION_COOKIE_STATS;
@@ -1465,6 +1466,7 @@ qemuMigrationEatCookie(virQEMUDriverPtr driver,
unsigned int flags)
{
g_autoptr(qemuMigrationCookie) mig = NULL;
+ qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
/* Parse & validate incoming cookie (if any) */
if (cookiein && cookieinlen &&
@@ -1513,7 +1515,7 @@ qemuMigrationEatCookie(virQEMUDriverPtr driver,
}
if (flags & QEMU_MIGRATION_COOKIE_STATS && mig->jobInfo)
- mig->jobInfo->operation = priv->job.current->operation;
+ mig->jobInfo->operation = jobPriv->current->operation;
return g_steal_pointer(&mig);
}
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index ec6ca14bbd..f0126bb0ef 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -656,6 +656,7 @@ qemuProcessHandleStop(qemuMonitorPtr mon G_GNUC_UNUSED,
virDomainEventSuspendedDetailType detail;
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
virObjectLock(vm);
@@ -667,7 +668,7 @@ qemuProcessHandleStop(qemuMonitorPtr mon G_GNUC_UNUSED,
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING &&
!priv->pausedShutdown) {
if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT) {
- if (priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY)
+ if (jobPriv->current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY)
reason = VIR_DOMAIN_PAUSED_POSTCOPY;
else
reason = VIR_DOMAIN_PAUSED_MIGRATION;
@@ -679,8 +680,8 @@ qemuProcessHandleStop(qemuMonitorPtr mon G_GNUC_UNUSED,
vm->def->name, virDomainPausedReasonTypeToString(reason),
detail);
- if (priv->job.current)
- ignore_value(virTimeMillisNow(&priv->job.current->stopped));
+ if (jobPriv->current)
+ ignore_value(virTimeMillisNow(&jobPriv->current->stopped));
if (priv->signalStop)
virDomainObjBroadcast(vm);
@@ -1648,6 +1649,7 @@ qemuProcessHandleMigrationStatus(qemuMonitorPtr mon G_GNUC_UNUSED,
void *opaque)
{
qemuDomainObjPrivatePtr priv;
+ qemuDomainJobPrivatePtr jobPriv;
virQEMUDriverPtr driver = opaque;
virObjectEventPtr event = NULL;
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
@@ -1660,12 +1662,13 @@ qemuProcessHandleMigrationStatus(qemuMonitorPtr mon G_GNUC_UNUSED,
qemuMonitorMigrationStatusTypeToString(status));
priv = vm->privateData;
+ jobPriv = priv->job.privateData;
if (priv->job.asyncJob == QEMU_ASYNC_JOB_NONE) {
VIR_DEBUG("got MIGRATION event without a migration job");
goto cleanup;
}
- priv->job.current->stats.mig.status = status;
+ jobPriv->current->stats.mig.status = status;
virDomainObjBroadcast(vm);
if (status == QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY &&
@@ -1746,13 +1749,13 @@ qemuProcessHandleDumpCompleted(qemuMonitorPtr mon G_GNUC_UNUSED,
goto cleanup;
}
jobPriv->dumpCompleted = true;
- priv->job.current->stats.dump = *stats;
+ jobPriv->current->stats.dump = *stats;
priv->job.error = g_strdup(error);
/* Force error if extracting the DUMP_COMPLETED status failed */
if (!error && status < 0) {
priv->job.error = g_strdup(virGetLastErrorMessage());
- priv->job.current->stats.dump.status = QEMU_MONITOR_DUMP_STATUS_FAILED;
+ jobPriv->current->stats.dump.status = QEMU_MONITOR_DUMP_STATUS_FAILED;
}
virDomainObjBroadcast(vm);
@@ -3266,6 +3269,7 @@ int qemuProcessStopCPUs(virQEMUDriverPtr driver,
{
int ret = -1;
qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
VIR_FREE(priv->lockState);
@@ -3284,8 +3288,8 @@ int qemuProcessStopCPUs(virQEMUDriverPtr driver,
/* de-activate netdevs after stopping CPUs */
ignore_value(qemuInterfaceStopDevices(vm->def));
- if (priv->job.current)
- ignore_value(virTimeMillisNow(&priv->job.current->stopped));
+ if (jobPriv->current)
+ ignore_value(virTimeMillisNow(&jobPriv->current->stopped));
/* The STOP event handler will change the domain state with the reason
* saved in priv->pausedReason and it will also emit corresponding domain
@@ -3582,6 +3586,7 @@ qemuProcessRecoverJob(virQEMUDriverPtr driver,
unsigned int *stopFlags)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
virDomainState state;
int reason;
unsigned long long now;
@@ -3650,11 +3655,11 @@ qemuProcessRecoverJob(virQEMUDriverPtr driver,
/* We reset the job parameters for backup so that the job will look
* active. This is possible because we are able to recover the state
* of blockjobs and also the backup job allows all sub-job types */
- priv->job.current = g_new0(qemuDomainJobInfo, 1);
- priv->job.current->operation = VIR_DOMAIN_JOB_OPERATION_BACKUP;
- priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP;
- priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_ACTIVE;
- priv->job.current->started = now;
+ jobPriv->current = g_new0(qemuDomainJobInfo, 1);
+ jobPriv->current->operation = VIR_DOMAIN_JOB_OPERATION_BACKUP;
+ jobPriv->current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP;
+ jobPriv->current->status = QEMU_DOMAIN_JOB_STATUS_ACTIVE;
+ jobPriv->current->started = now;
break;
case QEMU_ASYNC_JOB_NONE:
@@ -3759,7 +3764,6 @@ qemuDomainPerfRestart(virDomainObjPtr vm)
return 0;
}
-
static void
qemuProcessReconnectCheckMemAliasOrderMismatch(virDomainObjPtr vm)
{
--
2.25.1
4 years, 5 months
[PATCH 0/2] commandtest: Make 'test4' more reliable
by Peter Krempa
See 2/2 for the explanation.
Peter Krempa (2):
vircommand: REPRODUCER: Add artificial timeout before exitting
daemonization helper
tests: commandtest: Make 'test4' checking daemonization more reliable
src/util/vircommand.c | 1 +
tests/commanddata/test4.log | 1 +
tests/commandhelper.c | 17 ++++++++++++++++-
tests/commandtest.c | 3 ++-
4 files changed, 20 insertions(+), 2 deletions(-)
--
2.26.2
4 years, 5 months
[PATCH] docs: Mention unsupported hypervisors of transient element
by Han Han
Signed-off-by: Han Han <hhan(a)redhat.com>
---
docs/formatdomain.html.in | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index f3a639b972..c180b59226 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -4092,7 +4092,8 @@
contents should be reverted automatically when the guest
exits. With some hypervisors, marking a disk transient
prevents the domain from participating in migration or
- snapshots. <span class="since">Since 0.9.5</span>
+ snapshots. Unsuppported by qemu, libxl, vz hypervisors.
+ <span class="since">Since 0.9.5</span>
</dd>
<dt><code>serial</code></dt>
<dd>If present, this specify serial number of virtual hard drive.
--
2.27.0
4 years, 5 months
[PATCH] util: refactor code to workaround gcc 10.1.0 bug
by Daniel P. Berrangé
gcc 10.1.0 on Debian sid has a bug where the bounds checking gets
confused beteen two branches:
In file included from /usr/include/string.h:495,
from ../../src/internal.h:28,
from ../../src/util/virsocket.h:21,
from ../../src/util/virsocketaddr.h:21,
from ../../src/util/virnetdevip.h:21,
from ../../src/util/virnetdevip.c:21:
In function 'memcpy',
inlined from 'virNetDevGetifaddrsAddress' at ../../src/util/virnetdevip.c:914:13,
inlined from 'virNetDevIPAddrGet' at ../../src/util/virnetdevip.c:962:16:
/usr/include/arm-linux-gnueabihf/bits/string_fortified.h:34:10: error: '__builtin_memcpy' offset [16, 27] from the object at 'addr' is out of the bounds of referenced subobject 'inet4' with type 'struct sockaddr_in' at offset 0 [-Werror=array-bounds]
34 | return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../../src/util/virnetdevip.h:21,
from ../../src/util/virnetdevip.c:21:
../../src/util/virnetdevip.c: In function 'virNetDevIPAddrGet':
../../src/util/virsocketaddr.h:29:28: note: subobject 'inet4' declared here
29 | struct sockaddr_in inet4;
| ^~~~~
cc1: all warnings being treated as errors
Note the source location is pointing to the "inet6" / AF_INET6 branch of
the "if", but is complaining about bounds of the "inet4" field. Changing
the code into a switch() is sufficient to avoid triggering the bug and
is arguably better code too.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/util/virnetdevip.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/src/util/virnetdevip.c b/src/util/virnetdevip.c
index ba9e567e5a..8b85c7beca 100644
--- a/src/util/virnetdevip.c
+++ b/src/util/virnetdevip.c
@@ -897,26 +897,25 @@ virNetDevGetifaddrsAddress(const char *ifname,
}
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
- int family;
-
if (STRNEQ_NULLABLE(ifa->ifa_name, ifname))
continue;
if (!ifa->ifa_addr)
continue;
- family = ifa->ifa_addr->sa_family;
-
- if (family != AF_INET6 && family != AF_INET)
- continue;
- if (family == AF_INET6) {
+ switch (ifa->ifa_addr->sa_family) {
+ case AF_INET6:
addr->len = sizeof(addr->data.inet6);
memcpy(&addr->data.inet6, ifa->ifa_addr, addr->len);
- } else {
+ break;
+ case AF_INET:
addr->len = sizeof(addr->data.inet4);
memcpy(&addr->data.inet4, ifa->ifa_addr, addr->len);
+ break;
+ default:
+ continue;
}
- addr->data.stor.ss_family = family;
+ addr->data.stor.ss_family = ifa->ifa_addr->sa_family;
ret = 0;
goto cleanup;
}
--
2.24.1
4 years, 5 months
[PATCH 1/4] bhyve: implement sound device support
by Roman Bogorodskiy
bhyve supports intel hda sound devices that could be specified
on the command like using "-1:0,hda,play=$play_dev,rec=$rec_dev",
where "1:0" is a PCI address, and "$play_dev" and "$rec_dev"
point to the playback and recording device on the host respectively.
Currently, schema of the 'sound' element doesn't allow specifying
neither playback nor recording devices, so for now hardcode
/dev/dsp0, which is the first audio device on the host.
One more simplification is to stick to "ich6" model, however
the device shows as "ich7" in a guest.
Signed-off-by: Roman Bogorodskiy <bogorodskiy(a)gmail.com>
---
src/bhyve/bhyve_capabilities.c | 14 ++++++++
src/bhyve/bhyve_capabilities.h | 1 +
src/bhyve/bhyve_command.c | 33 +++++++++++++++++
src/bhyve/bhyve_device.c | 9 +++++
.../bhyvexml2argv-sound.args | 10 ++++++
.../bhyvexml2argv-sound.ldargs | 3 ++
.../bhyvexml2argvdata/bhyvexml2argv-sound.xml | 24 +++++++++++++
tests/bhyvexml2argvtest.c | 6 +++-
.../bhyvexml2xmlout-sound.xml | 36 +++++++++++++++++++
tests/bhyvexml2xmltest.c | 1 +
10 files changed, 136 insertions(+), 1 deletion(-)
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-sound.args
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-sound.ldargs
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-sound.xml
create mode 100644 tests/bhyvexml2xmloutdata/bhyvexml2xmlout-sound.xml
diff --git a/src/bhyve/bhyve_capabilities.c b/src/bhyve/bhyve_capabilities.c
index fb8829d571..36f3985335 100644
--- a/src/bhyve/bhyve_capabilities.c
+++ b/src/bhyve/bhyve_capabilities.c
@@ -323,6 +323,17 @@ bhyveProbeCapsXHCIController(unsigned int *caps, char *binary)
}
+static int
+bhyveProbeCapsSoundHda(unsigned int *caps, char *binary)
+{
+ return bhyveProbeCapsDeviceHelper(caps, binary,
+ "-s",
+ "0,hda",
+ "pci slot 0:0: unknown device \"hda\"",
+ BHYVE_CAP_SOUND_HDA);
+}
+
+
int
virBhyveProbeCaps(unsigned int *caps)
{
@@ -351,6 +362,9 @@ virBhyveProbeCaps(unsigned int *caps)
if ((ret = bhyveProbeCapsXHCIController(caps, binary)))
goto out;
+ if ((ret = bhyveProbeCapsSoundHda(caps, binary)))
+ goto out;
+
out:
VIR_FREE(binary);
return ret;
diff --git a/src/bhyve/bhyve_capabilities.h b/src/bhyve/bhyve_capabilities.h
index 12926cf423..1ac9ff4283 100644
--- a/src/bhyve/bhyve_capabilities.h
+++ b/src/bhyve/bhyve_capabilities.h
@@ -49,6 +49,7 @@ typedef enum {
BHYVE_CAP_FBUF = 1 << 4,
BHYVE_CAP_XHCI = 1 << 5,
BHYVE_CAP_CPUTOPOLOGY = 1 << 6,
+ BHYVE_CAP_SOUND_HDA = 1 << 7,
} virBhyveCapsFlags;
int virBhyveProbeGrubCaps(virBhyveGrubCapsFlags *caps);
diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c
index 22d0b24ec4..64af0b3598 100644
--- a/src/bhyve/bhyve_command.c
+++ b/src/bhyve/bhyve_command.c
@@ -475,6 +475,34 @@ bhyveBuildGraphicsArgStr(const virDomainDef *def,
}
+static int
+bhyveBuildSoundArgStr(const virDomainDef *def G_GNUC_UNUSED,
+ virDomainSoundDefPtr sound,
+ bhyveConnPtr driver,
+ virCommandPtr cmd)
+{
+ if (!(bhyveDriverGetBhyveCaps(driver) & BHYVE_CAP_SOUND_HDA)) {
+ /* Currently, bhyve only supports "hda" sound devices, so
+ if it's not supported, sound devices are not supported at all */
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Sound devices emulation is not supported "
+ "by given bhyve binary"));
+ return -1;
+ }
+
+ if (sound->model != VIR_DOMAIN_SOUND_MODEL_ICH6) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Sound device model is not supported"));
+ return -1;
+ }
+
+ virCommandAddArg(cmd, "-s");
+ virCommandAddArgFormat(cmd, "%d:%d,hda,play=/dev/dsp0",
+ sound->info.addr.pci.slot,
+ sound->info.addr.pci.function);
+ return 0;
+}
+
virCommandPtr
virBhyveProcessBuildBhyveCmd(bhyveConnPtr driver, virDomainDefPtr def,
bool dryRun)
@@ -619,6 +647,11 @@ virBhyveProcessBuildBhyveCmd(bhyveConnPtr driver, virDomainDefPtr def,
}
}
+ for (i = 0; i < def->nsounds; i++) {
+ if (bhyveBuildSoundArgStr(def, def->sounds[i], driver, cmd) < 0)
+ goto error;
+ }
+
if (bhyveDomainDefNeedsISAController(def))
bhyveBuildLPCArgStr(def, cmd);
diff --git a/src/bhyve/bhyve_device.c b/src/bhyve/bhyve_device.c
index fc52280361..3c8ff587e0 100644
--- a/src/bhyve/bhyve_device.c
+++ b/src/bhyve/bhyve_device.c
@@ -154,6 +154,15 @@ bhyveAssignDevicePCISlots(virDomainDefPtr def,
return -1;
}
+ for (i = 0; i < def->nsounds; i++) {
+ if (!virDeviceInfoPCIAddressIsWanted(&def->sounds[i]->info))
+ continue;
+ if (virDomainPCIAddressReserveNextAddr(addrs,
+ &def->sounds[i]->info,
+ VIR_PCI_CONNECT_TYPE_PCI_DEVICE,
+ -1) < 0)
+ return -1;
+ }
return 0;
}
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-sound.args b/tests/bhyvexml2argvdata/bhyvexml2argv-sound.args
new file mode 100644
index 0000000000..c242708ff1
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-sound.args
@@ -0,0 +1,10 @@
+/usr/sbin/bhyve \
+-c 1 \
+-m 214 \
+-u \
+-H \
+-P \
+-s 0:0,hostbridge \
+-s 2:0,ahci,hd:/tmp/freebsd.img \
+-s 3:0,virtio-net,faketapdev,mac=52:54:00:b9:94:02 \
+-s 4:0,hda,play=/dev/dsp0 bhyve
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-sound.ldargs b/tests/bhyvexml2argvdata/bhyvexml2argv-sound.ldargs
new file mode 100644
index 0000000000..32538b558e
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-sound.ldargs
@@ -0,0 +1,3 @@
+/usr/sbin/bhyveload \
+-m 214 \
+-d /tmp/freebsd.img bhyve
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-sound.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-sound.xml
new file mode 100644
index 0000000000..dd4f0491a2
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-sound.xml
@@ -0,0 +1,24 @@
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+ <memory>219136</memory>
+ <vcpu>1</vcpu>
+ <os>
+ <type>hvm</type>
+ </os>
+ <devices>
+ <disk type='file'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/freebsd.img'/>
+ <target dev='hda' bus='sata'/>
+ <address type='drive' controller='0' bus='0' target='2' unit='0'/>
+ </disk>
+ <interface type='bridge'>
+ <mac address='52:54:00:b9:94:02'/>
+ <model type='virtio'/>
+ <source bridge="virbr0"/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </interface>
+ <sound model='ich6'/>
+ </devices>
+</domain>
diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c
index 9e7eb218b8..179a73bb42 100644
--- a/tests/bhyvexml2argvtest.c
+++ b/tests/bhyvexml2argvtest.c
@@ -175,7 +175,7 @@ mymain(void)
driver.bhyvecaps = BHYVE_CAP_RTC_UTC | BHYVE_CAP_AHCI32SLOT | \
BHYVE_CAP_NET_E1000 | BHYVE_CAP_LPC_BOOTROM | \
BHYVE_CAP_FBUF | BHYVE_CAP_XHCI | \
- BHYVE_CAP_CPUTOPOLOGY;
+ BHYVE_CAP_CPUTOPOLOGY | BHYVE_CAP_SOUND_HDA;
DO_TEST("base");
DO_TEST("wired");
@@ -210,6 +210,7 @@ mymain(void)
DO_TEST_FAILURE("cputopology-nvcpu-mismatch");
DO_TEST("commandline");
DO_TEST("msrs");
+ DO_TEST("sound");
/* Address allocation tests */
DO_TEST("addr-single-sata-disk");
@@ -249,6 +250,9 @@ mymain(void)
driver.bhyvecaps &= ~BHYVE_CAP_CPUTOPOLOGY;
DO_TEST_FAILURE("cputopology");
+ driver.bhyvecaps &= ~BHYVE_CAP_SOUND_HDA;
+ DO_TEST_FAILURE("sound");
+
virObjectUnref(driver.caps);
virObjectUnref(driver.xmlopt);
virPortAllocatorRangeFree(driver.remotePorts);
diff --git a/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-sound.xml b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-sound.xml
new file mode 100644
index 0000000000..f5da7c23c8
--- /dev/null
+++ b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-sound.xml
@@ -0,0 +1,36 @@
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64'>hvm</type>
+ <boot dev='hd'/>
+ </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'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/freebsd.img'/>
+ <target dev='hda' bus='sata'/>
+ <address type='drive' controller='0' bus='0' target='2' unit='0'/>
+ </disk>
+ <controller type='pci' index='0' model='pci-root'/>
+ <controller type='sata' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </controller>
+ <interface type='bridge'>
+ <mac address='52:54:00:b9:94:02'/>
+ <source bridge='virbr0'/>
+ <model type='virtio'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </interface>
+ <sound model='ich6'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+ </sound>
+ </devices>
+</domain>
diff --git a/tests/bhyvexml2xmltest.c b/tests/bhyvexml2xmltest.c
index a0c20a14c1..9e40e1ca2e 100644
--- a/tests/bhyvexml2xmltest.c
+++ b/tests/bhyvexml2xmltest.c
@@ -110,6 +110,7 @@ mymain(void)
DO_TEST_DIFFERENT("vnc-autoport");
DO_TEST_DIFFERENT("commandline");
DO_TEST_DIFFERENT("msrs");
+ DO_TEST_DIFFERENT("sound");
/* Address allocation tests */
DO_TEST_DIFFERENT("addr-single-sata-disk");
--
2.27.0
4 years, 5 months
[libvirt PATCH] qemu: Fix affinity typo
by Ján Tomko
Fixes: 4c0398b5284d14c55eca51095673b6fadbbd85fb
Signed-off-by: Ján Tomko <jtomko(a)redhat.com>
---
Pushed as trivial.
src/qemu/qemu_process.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 1006f41614..ec6ca14bbd 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2653,7 +2653,7 @@ qemuProcessSetupPid(virDomainObjPtr vm,
virDomainNumatuneMemMode mem_mode;
virCgroupPtr cgroup = NULL;
virBitmapPtr use_cpumask = NULL;
- virBitmapPtr afinity_cpumask = NULL;
+ virBitmapPtr affinity_cpumask = NULL;
g_autoptr(virBitmap) hostcpumap = NULL;
g_autofree char *mem_mask = NULL;
int ret = -1;
@@ -2679,7 +2679,7 @@ qemuProcessSetupPid(virDomainObjPtr vm,
* its config file */
if (qemuProcessGetAllCpuAffinity(&hostcpumap) < 0)
goto cleanup;
- afinity_cpumask = hostcpumap;
+ affinity_cpumask = hostcpumap;
}
/*
@@ -2720,11 +2720,11 @@ qemuProcessSetupPid(virDomainObjPtr vm,
}
- if (!afinity_cpumask)
- afinity_cpumask = use_cpumask;
+ if (!affinity_cpumask)
+ affinity_cpumask = use_cpumask;
/* Setup legacy affinity. */
- if (afinity_cpumask && virProcessSetAffinity(pid, afinity_cpumask) < 0)
+ if (affinity_cpumask && virProcessSetAffinity(pid, affinity_cpumask) < 0)
goto cleanup;
/* Set scheduler type and priority, but not for the main thread. */
--
2.26.2
4 years, 5 months
Format/style of UI message
by Pino Toscano
Hi,
I recently took a look at the UI/user visible messages from libvirt,
which are translated using gettext. They are extracted in a single
libvirt.pot catalog, which includes messages from libvirt.so itself
(mostly, if not all, errors), the separate daemons, the helper tools,
and from virsh.
I noticed there is plently of room for improvements: what strikes is
the lack of consistency among the messages. Let me state first: I
understand that not all the people are native English speakers
(I am not), so I'm not picking against anyone.
Some examples:
a) different capitalization:
- "cannot open %s"
- "Cannot open %s"
b) different quoting for files/identifiers/etc:
- "Cannot open %s"
- "Cannot open '%s'"
c) different verbs for failed actions:
- "Cannot frobnicate ..."
- "Could not frobnicate ..."
- "Did not frobnicate ..."
- "Failed to frobnicate ..."
- "Unable to frobnicate ..."
depending on the message, also "frobbing failed"
d) sometimes contractions ("couldn't", "don't", etc), sometimes not
("could not", "do not", etc)
e) what QEMU/etc supports:
- "... by this QEMU binary"
- "... for this QEMU binary"
- "... in this QEMU binary"
- "... with this QEMU binary"
- "... by this QEMU"
- "... for this QEMU"
- "... with this QEMU"
- "... with this binary" [in a QEMU file]
- "... [supported] by qemu"
there is also "qemu does not support ...", which I think it can stay
for now; also both "available [by/for/etc]" and "supported [by/for/etc]"
are used
I can give it a try in fixing the messages to be more consistent all
around; before I start the mass editing, I need to know which style to
follow:
a) it seems like the virError fields @message, @str1, @str2 and @str3
are joined together in reporting/log strings like "error: <text>";
hence, should they be not capitalized? It may look OK in English, but
less nice and hard to fix in translations.
Obviously, sentences as shown in tools (e.g. virsh) definitely need to
be properly capitalized.
b) should identifiers such as filenames, paths, XML tags, JSON fields,
etc be always quoted?
c) which verb to use when something failed? "could not" is a subjective
thing, not a past action; "failed" seems to imply that something was
attempted; "did not" seems to imply that it was not done, but nothing
whether it was attempted; the rest sort of indicate the ability to do
something.
d) allow contractions or not? They are generally used in spoken/informal
language, and while libvirt is not that formal it should not be that
colloquial either IMHO; also, they make the text slightly harder to
understand by non-native speakers, and they are lost when translating.
A POV on the matter is:
https://www.businesswritingblog.com/business_writing/2006/04/dont_use_con...
e) which message to use to indicate that QEMU does not support
something?
Thanks,
--
Pino Toscano
4 years, 5 months