[libvirt] [PATCH 2/6] Add support for fetching statistics of completed jobs
John Ferlan
jferlan at redhat.com
Fri Sep 5 18:42:00 UTC 2014
On 09/01/2014 11:05 AM, Jiri Denemark wrote:
> virDomainGetJobStats gains new VIR_DOMAIN_JOB_STATS_COMPLETED flag that
> can be used to fetch statistics of a completed job rather than a
> currently running job.
>
> Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
> ---
> include/libvirt/libvirt.h.in | 11 +++++++++++
> src/libvirt.c | 8 +++++++-
> src/qemu/qemu_domain.c | 1 +
> src/qemu/qemu_domain.h | 1 +
> src/qemu/qemu_driver.c | 25 +++++++++++++++++++------
> src/qemu/qemu_migration.c | 6 ++++++
> src/qemu/qemu_monitor_json.c | 3 ++-
> 7 files changed, 47 insertions(+), 8 deletions(-)
>
This seems AOK - see my note at the end about qemu_monitor_json.c though.
> diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
> index 9358314..9670e06 100644
> --- a/include/libvirt/libvirt.h.in
> +++ b/include/libvirt/libvirt.h.in
> @@ -4306,6 +4306,17 @@ struct _virDomainJobInfo {
> unsigned long long fileRemaining;
> };
>
> +/**
> + * virDomainGetJobStatsFlags:
> + *
> + * Flags OR'ed together to provide specific behavior when querying domain
> + * job statistics.
> + */
> +typedef enum {
> + VIR_DOMAIN_JOB_STATS_COMPLETED = 1 << 0, /* return stats of a recently
> + * completed job */
> +} virDomainGetJobStatsFlags;
> +
> int virDomainGetJobInfo(virDomainPtr dom,
> virDomainJobInfoPtr info);
> int virDomainGetJobStats(virDomainPtr domain,
> diff --git a/src/libvirt.c b/src/libvirt.c
> index 5d8f01c..6fa0a6b 100644
> --- a/src/libvirt.c
> +++ b/src/libvirt.c
> @@ -17567,7 +17567,7 @@ virDomainGetJobInfo(virDomainPtr domain, virDomainJobInfoPtr info)
> * @type: where to store the job type (one of virDomainJobType)
> * @params: where to store job statistics
> * @nparams: number of items in @params
> - * @flags: extra flags; not used yet, so callers should always pass 0
> + * @flags: bitwise-OR of virDomainGetJobStatsFlags
> *
> * Extract information about progress of a background job on a domain.
> * Will return an error if the domain is not active. The function returns
> @@ -17577,6 +17577,12 @@ virDomainGetJobInfo(virDomainPtr domain, virDomainJobInfoPtr info)
> * may receive fields that they do not understand in case they talk to a
> * newer server.
> *
> + * When @flags contains VIR_DOMAIN_JOB_STATS_COMPLETED, the function will
> + * return statistics about a recently completed job. Specifically, this
> + * flag may be used to query statistics of a completed incoming migration.
> + * Statistics of a completed job are automatically destroyed once read or
> + * when libvirtd is restarted.
> + *
^^^^^^^^^
Yeah - my question from patch 1 with respect to checking access for
job.current especially... The job.completed seems fine.
> * Returns 0 in case of success and -1 in case of failure.
> */
> int
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index 2c709e9..18a3761 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -199,6 +199,7 @@ static void
> qemuDomainObjFreeJob(qemuDomainObjPrivatePtr priv)
> {
> VIR_FREE(priv->job.current);
> + VIR_FREE(priv->job.completed);
> virCondDestroy(&priv->job.cond);
> virCondDestroy(&priv->job.asyncCond);
> }
> diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
> index 119590e..365238b 100644
> --- a/src/qemu/qemu_domain.h
> +++ b/src/qemu/qemu_domain.h
> @@ -124,6 +124,7 @@ struct qemuDomainJobObj {
> unsigned long long mask; /* Jobs allowed during async job */
> bool dump_memory_only; /* use dump-guest-memory to do dump */
> qemuDomainJobInfoPtr current; /* async job progress data */
> + qemuDomainJobInfoPtr completed; /* statistics data of a recently completed job */
> bool asyncAbort; /* abort of async job requested */
> };
>
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 265315d..cd6932a 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -11651,9 +11651,10 @@ qemuDomainGetJobStats(virDomainPtr dom,
> {
> virDomainObjPtr vm;
> qemuDomainObjPrivatePtr priv;
> + qemuDomainJobInfoPtr jobInfo;
> int ret = -1;
>
> - virCheckFlags(0, -1);
> + virCheckFlags(VIR_DOMAIN_JOB_STATS_COMPLETED, -1);
>
> if (!(vm = qemuDomObjFromDomain(dom)))
> goto cleanup;
> @@ -11663,13 +11664,19 @@ qemuDomainGetJobStats(virDomainPtr dom,
> if (virDomainGetJobStatsEnsureACL(dom->conn, vm->def) < 0)
> goto cleanup;
>
> - if (!virDomainObjIsActive(vm)) {
> + if (!(flags & VIR_DOMAIN_JOB_STATS_COMPLETED) &&
> + !virDomainObjIsActive(vm)) {
> virReportError(VIR_ERR_OPERATION_INVALID,
> "%s", _("domain is not running"));
> goto cleanup;
> }
>
> - if (!priv->job.current) {
> + if (flags & VIR_DOMAIN_JOB_STATS_COMPLETED)
> + jobInfo = priv->job.completed;
> + else
> + jobInfo = priv->job.current;
> +
> + if (!jobInfo) {
> *type = VIR_DOMAIN_JOB_NONE;
> *params = NULL;
> *nparams = 0;
Here there is a check for job.{completed|current} before access
> @@ -11682,11 +11689,17 @@ qemuDomainGetJobStats(virDomainPtr dom,
> * of incoming migration which we don't currently
> * monitor actively in the background thread
> */
> - if (qemuDomainJobInfoUpdateTime(priv->job.current) < 0 ||
> - qemuDomainJobInfoToParams(priv->job.current,
> - type, params, nparams) < 0)
> + if ((jobInfo->type == VIR_DOMAIN_JOB_BOUNDED ||
> + jobInfo->type == VIR_DOMAIN_JOB_UNBOUNDED) &&
> + qemuDomainJobInfoUpdateTime(jobInfo) < 0)
> goto cleanup;
>
> + if (qemuDomainJobInfoToParams(jobInfo, type, params, nparams) < 0)
> + goto cleanup;
> +
> + if (flags & VIR_DOMAIN_JOB_STATS_COMPLETED)
> + VIR_FREE(priv->job.completed);
> +
> ret = 0;
>
> cleanup:
> diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
> index 64adab4..208a21f 100644
> --- a/src/qemu/qemu_migration.c
> +++ b/src/qemu/qemu_migration.c
> @@ -1839,6 +1839,9 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver,
> }
>
> if (jobInfo->type == VIR_DOMAIN_JOB_COMPLETED) {
> + VIR_FREE(priv->job.completed);
> + if (VIR_ALLOC(priv->job.completed) == 0)
> + *priv->job.completed = *jobInfo;
> return 0;
> } else if (jobInfo->type == VIR_DOMAIN_JOB_UNBOUNDED) {
> /* The migration was aborted by us rather than QEMU itself so let's
> @@ -3418,6 +3421,9 @@ qemuMigrationRun(virQEMUDriverPtr driver,
> VIR_FORCE_CLOSE(fd);
> }
>
> + if (priv->job.completed)
> + qemuDomainJobInfoUpdateTime(priv->job.completed);
> +
Here there is a check for job.completed before usage
> cookieFlags |= QEMU_MIGRATION_COOKIE_NETWORK;
> if (flags & VIR_MIGRATE_PERSIST_DEST)
> cookieFlags |= QEMU_MIGRATION_COOKIE_PERSISTENT;
> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
> index 62e7d5d..263fa8b 100644
> --- a/src/qemu/qemu_monitor_json.c
> +++ b/src/qemu/qemu_monitor_json.c
> @@ -2478,7 +2478,8 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
> if (rc == 0)
> status->downtime_set = true;
>
> - if (status->status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE) {
> + if (status->status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE ||
> + status->status == QEMU_MONITOR_MIGRATION_STATUS_COMPLETED) {
> virJSONValuePtr ram = virJSONValueObjectGet(ret, "ram");
> if (!ram) {
> virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
>
While you're in this module - the following 3 calls don't check status
(and were flagged by my new coverity):
virJSONValueObjectGetNumberUlong(ret, "total-time", &status->total_time);
virJSONValueObjectGetNumberUlong(ram, "normal", &status->ram_normal);
virJSONValueObjectGetNumberUlong(ram, "normal-bytes",
&status->ram_normal_bytes);
I know "somewhat" outside the bounds of these changes but since they're
in qemuMonitorJSONGetMigrationStatusReply() and used by the changes here
- there's enough of a reason to adjust that I think.
I don't see where "total_time" is ever used though...
John
More information about the libvir-list
mailing list