]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: backup: Implement stats gathering while the job is running
authorPeter Krempa <pkrempa@redhat.com>
Tue, 26 Nov 2019 17:25:49 +0000 (18:25 +0100)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 10 Dec 2019 11:41:58 +0000 (12:41 +0100)
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@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/qemu/qemu_backup.c
src/qemu/qemu_backup.h
src/qemu/qemu_driver.c

index 72cd9a459a35b2e699df77253302aadf627a4f30..c9709dc29ae79ebc32314afeb9b2643cfe2e4080 100644 (file)
@@ -938,3 +938,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;
+}
index 96297fc9e41eab16afa8062f963d196fb95a2683..0f76abe067f12e73f84f0d580c65946425a9ece2 100644 (file)
@@ -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);
index f2967c787a56cd24a12c0b6de3c649f9c4e5c561..5d42a5e7238b3f8b229d7c8623b0aeae2c2e77e8 100644 (file)
@@ -13860,7 +13860,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: