[libvirt] [PATCH 19/21] qemu: backup: Implement stats gathering while the job is running

Peter Krempa pkrempa at redhat.com
Tue Nov 26 21:40:05 UTC 2019


We can use the output of 'query-jobs' to figure out some useful
information about a backup job. That is progress in case of a push job
and scratch file use in case of a pull job.

Add a worker which will total up the data and call it from
qemuDomainGetJobStatsInternal.

Signed-off-by: Peter Krempa <pkrempa at redhat.com>
---
 src/qemu/qemu_backup.c | 98 ++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_backup.h |  5 +++
 src/qemu/qemu_driver.c |  3 +-
 3 files changed, 105 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
index 771e22ccd7..510d708788 100644
--- a/src/qemu/qemu_backup.c
+++ b/src/qemu/qemu_backup.c
@@ -917,3 +917,101 @@ qemuBackupNotifyBlockjobEnd(virDomainObjPtr vm,

     /* otherwise we must wait for the jobs to end */
 }
+
+
+static void
+qemuBackupGetJobInfoStatsUpdateOne(virDomainObjPtr vm,
+                                   bool push,
+                                   const char *diskdst,
+                                   qemuDomainBackupStats *stats,
+                                   qemuMonitorJobInfoPtr *blockjobs,
+                                   size_t nblockjobs)
+{
+    virDomainDiskDefPtr domdisk;
+    qemuMonitorJobInfoPtr monblockjob = NULL;
+    g_autoptr(qemuBlockJobData) diskblockjob = NULL;
+    size_t i;
+
+    /* it's just statistics so let's not worry so much about errors */
+    if (!(domdisk = virDomainDiskByTarget(vm->def, diskdst)))
+        return;
+
+    if (!(diskblockjob = qemuBlockJobDiskGetJob(domdisk)))
+        return;
+
+    for (i = 0; i < nblockjobs; i++) {
+        if (STREQ_NULLABLE(blockjobs[i]->id, diskblockjob->name)) {
+            monblockjob = blockjobs[i];
+            break;
+        }
+    }
+    if (!monblockjob)
+        return;
+
+    if (push) {
+        stats->total += monblockjob->progressTotal;
+        stats->transferred += monblockjob->progressCurrent;
+    } else {
+        stats->tmp_used += monblockjob->progressCurrent;
+        stats->tmp_total += monblockjob->progressTotal;
+    }
+}
+
+
+int
+qemuBackupGetJobInfoStats(virQEMUDriverPtr driver,
+                          virDomainObjPtr vm,
+                          qemuDomainJobInfoPtr jobInfo)
+{
+    qemuDomainBackupStats *stats = &jobInfo->stats.backup;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuMonitorJobInfoPtr *blockjobs = NULL;
+    size_t nblockjobs = 0;
+    size_t i;
+    int rc;
+    int ret = -1;
+
+    if (!priv->backup) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("backup job data missing"));
+        return -1;
+    }
+
+    if (qemuDomainJobInfoUpdateTime(jobInfo) < 0)
+        return -1;
+
+    jobInfo->status = QEMU_DOMAIN_JOB_STATUS_ACTIVE;
+
+    qemuDomainObjEnterMonitor(driver, vm);
+
+    rc = qemuMonitorGetJobInfo(priv->mon, &blockjobs, &nblockjobs);
+
+    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+        goto cleanup;
+
+    /* count in completed jobs */
+    stats->total = priv->backup->push_total;
+    stats->transferred = priv->backup->push_transferred;
+    stats->tmp_used = priv->backup->pull_tmp_used;
+    stats->tmp_total = priv->backup->pull_tmp_total;
+
+    for (i = 0; i < priv->backup->ndisks; i++) {
+        if (priv->backup->disks[i].state != VIR_DOMAIN_BACKUP_DISK_STATE_RUNNING)
+            continue;
+
+        qemuBackupGetJobInfoStatsUpdateOne(vm,
+                                           priv->backup->type == VIR_DOMAIN_BACKUP_TYPE_PUSH,
+                                           priv->backup->disks[i].name,
+                                           stats,
+                                           blockjobs,
+                                           nblockjobs);
+    }
+
+    ret = 0;
+
+ cleanup:
+    for (i = 0; i < nblockjobs; i++)
+        qemuMonitorJobInfoFree(blockjobs[i]);
+    g_free(blockjobs);
+    return ret;
+}
diff --git a/src/qemu/qemu_backup.h b/src/qemu/qemu_backup.h
index 96297fc9e4..0f76abe067 100644
--- a/src/qemu/qemu_backup.h
+++ b/src/qemu/qemu_backup.h
@@ -39,3 +39,8 @@ qemuBackupNotifyBlockjobEnd(virDomainObjPtr vm,
                             qemuBlockjobState state,
                             unsigned long long cur,
                             unsigned long long end);
+
+int
+qemuBackupGetJobInfoStats(virQEMUDriverPtr driver,
+                          virDomainObjPtr vm,
+                          qemuDomainJobInfoPtr jobInfo);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 4cf516a083..6bc9c7c6d7 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13901,7 +13901,8 @@ qemuDomainGetJobStatsInternal(virQEMUDriverPtr driver,
         break;

     case QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP:
-        /* TODO implement for backup job */
+        if (qemuBackupGetJobInfoStats(driver, vm, jobInfo) < 0)
+            goto cleanup;
         break;

     case QEMU_DOMAIN_JOB_STATS_TYPE_NONE:
-- 
2.23.0




More information about the libvir-list mailing list