[PATCH v3 09/11] test_driver: Implement virConnectGetAllDomainStats

Luke Yue posted 11 patches 4 years, 6 months ago
There is a newer version of this series
[PATCH v3 09/11] test_driver: Implement virConnectGetAllDomainStats
Posted by Luke Yue 4 years, 6 months ago
Implement virConnectGetAllDomainStats in a modular way just like QEMU
driver, though remove some params in GetStatsWorker that we don't need
in test driver currently.

Only add the worker to get state so far, more worker will be added
in the future.

Signed-off-by: Luke Yue <lukedyue@gmail.com>
---
 src/test/test_driver.c | 135 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 135 insertions(+)

diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 1d439a89b6..6eebd85cf3 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -9785,6 +9785,140 @@ testDomainSetIOThreadParams(virDomainPtr dom,
     return ret;
 }
 
+static int
+testDomainGetStatsState(virDomainObj *dom,
+                        virTypedParamList *params)
+{
+    if (virTypedParamListAddInt(params, dom->state.state, "state.state") < 0)
+        return -1;
+
+    if (virTypedParamListAddInt(params, dom->state.reason, "state.reason") < 0)
+        return -1;
+
+    return 0;
+}
+
+typedef int
+(*testDomainGetStatsFunc)(virDomainObj *dom,
+                          virTypedParamList *list);
+
+struct testDomainGetStatsWorker {
+    testDomainGetStatsFunc func;
+    unsigned int stats;
+};
+
+static struct testDomainGetStatsWorker testDomainGetStatsWorkers[] = {
+    { testDomainGetStatsState, VIR_DOMAIN_STATS_STATE },
+    { NULL, 0 }
+};
+
+static int
+testDomainGetStats(virConnectPtr conn,
+                   virDomainObj *dom,
+                   unsigned int stats,
+                   virDomainStatsRecordPtr *record)
+{
+    g_autofree virDomainStatsRecordPtr tmp = NULL;
+    g_autoptr(virTypedParamList) params = NULL;
+    size_t i;
+
+    params = g_new0(virTypedParamList, 1);
+
+    for (i = 0; testDomainGetStatsWorkers[i].func; i++) {
+        if (stats & testDomainGetStatsWorkers[i].stats) {
+            if (testDomainGetStatsWorkers[i].func(dom, params) < 0)
+                return -1;
+        }
+    }
+
+    tmp = g_new0(virDomainStatsRecord, 1);
+
+    if (!(tmp->dom = virGetDomain(conn, dom->def->name,
+                                  dom->def->uuid, dom->def->id)))
+        return -1;
+
+    tmp->nparams = virTypedParamListStealParams(params, &tmp->params);
+    *record = g_steal_pointer(&tmp);
+    return 0;
+}
+
+static int
+testConnectGetAllDomainStats(virConnectPtr conn,
+                             virDomainPtr *doms,
+                             unsigned int ndoms,
+                             unsigned int stats,
+                             virDomainStatsRecordPtr **retStats,
+                             unsigned int flags)
+{
+    testDriver *driver = conn->privateData;
+    unsigned int lflags = flags & (VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE |
+                                   VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT |
+                                   VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE);
+
+    unsigned int supported = VIR_DOMAIN_STATS_STATE;
+    virDomainObj **vms = NULL;
+    size_t nvms;
+    virDomainStatsRecordPtr *tmpstats = NULL;
+    int nstats = 0;
+    int ret = -1;
+    size_t i;
+
+    virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE |
+                  VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT |
+                  VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE |
+                  VIR_CONNECT_GET_ALL_DOMAINS_STATS_NOWAIT |
+                  VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING |
+                  VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS, -1);
+
+    if (!stats) {
+        stats = supported;
+    } else if ((flags & VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS) &&
+               (stats & ~supported)) {
+        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
+                       _("Stats types bits 0x%x are not supported by this daemon"),
+                       stats & ~supported);
+        return -1;
+    }
+
+    if (ndoms) {
+        if (virDomainObjListConvert(driver->domains, conn, doms, ndoms, &vms,
+                                    &nvms, NULL, lflags, true) < 0)
+            return -1;
+    } else {
+        if (virDomainObjListCollect(driver->domains, conn, &vms, &nvms,
+                                    NULL, lflags) < 0)
+            return -1;
+    }
+
+    tmpstats = g_new0(virDomainStatsRecordPtr, nvms + 1);
+
+    for (i = 0; i < nvms; i++) {
+        virDomainStatsRecordPtr tmp = NULL;
+        virDomainObj *vm = vms[i];
+
+        virObjectLock(vm);
+
+        if ((testDomainGetStats(conn, vm, stats, &tmp)) < 0)
+            goto cleanup;
+
+        virObjectUnlock(vm);
+
+        if (!tmp)
+            goto cleanup;
+
+        tmpstats[nstats++] = tmp;
+    }
+
+    *retStats = g_steal_pointer(&tmpstats);
+    ret = nstats;
+
+ cleanup:
+    virDomainStatsRecordListFree(tmpstats);
+    virObjectListFreeCount(vms, nvms);
+
+    return ret;
+}
+
 /*
  * Test driver
  */
@@ -9799,6 +9933,7 @@ static virHypervisorDriver testHypervisorDriver = {
     .nodeGetCPUStats = testNodeGetCPUStats, /* 2.3.0 */
     .nodeGetFreeMemory = testNodeGetFreeMemory, /* 2.3.0 */
     .nodeGetFreePages = testNodeGetFreePages, /* 2.3.0 */
+    .connectGetAllDomainStats = testConnectGetAllDomainStats, /* 7.7.0 */
     .connectGetCapabilities = testConnectGetCapabilities, /* 0.2.1 */
     .connectGetSysinfo = testConnectGetSysinfo, /* 2.3.0 */
     .connectGetType = testConnectGetType, /* 2.3.0 */
-- 
2.32.0

Re: [PATCH v3 09/11] test_driver: Implement virConnectGetAllDomainStats
Posted by Luke Yue 4 years, 6 months ago
On Thu, 2021-08-12 at 18:50 +0800, Luke Yue wrote:
> Implement virConnectGetAllDomainStats in a modular way just like QEMU
> driver, though remove some params in GetStatsWorker that we don't need
> in test driver currently.
> 
> Only add the worker to get state so far, more worker will be added
> in the future.
> 
> Signed-off-by: Luke Yue <lukedyue@gmail.com>
> ---
>  src/test/test_driver.c | 135 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 135 insertions(+)
> 
> diff --git a/src/test/test_driver.c b/src/test/test_driver.c
> index 1d439a89b6..6eebd85cf3 100644
> --- a/src/test/test_driver.c
> +++ b/src/test/test_driver.c
> @@ -9785,6 +9785,140 @@ testDomainSetIOThreadParams(virDomainPtr dom,
>      return ret;
>  }
>  
> +static int
> +testDomainGetStatsState(virDomainObj *dom,
> +                        virTypedParamList *params)
> +{
> +    if (virTypedParamListAddInt(params, dom->state.state,
> "state.state") < 0)
> +        return -1;
> +
> +    if (virTypedParamListAddInt(params, dom->state.reason,
> "state.reason") < 0)
> +        return -1;
> +
> +    return 0;
> +}
> +
> +typedef int
> +(*testDomainGetStatsFunc)(virDomainObj *dom,
> +                          virTypedParamList *list);
> +
> +struct testDomainGetStatsWorker {
> +    testDomainGetStatsFunc func;
> +    unsigned int stats;
> +};
> +
> +static struct testDomainGetStatsWorker testDomainGetStatsWorkers[] = {
> +    { testDomainGetStatsState, VIR_DOMAIN_STATS_STATE },
> +    { NULL, 0 }
> +};
> +
> +static int
> +testDomainGetStats(virConnectPtr conn,
> +                   virDomainObj *dom,
> +                   unsigned int stats,
> +                   virDomainStatsRecordPtr *record)
> +{
> +    g_autofree virDomainStatsRecordPtr tmp = NULL;
> +    g_autoptr(virTypedParamList) params = NULL;
> +    size_t i;
> +
> +    params = g_new0(virTypedParamList, 1);
> +
> +    for (i = 0; testDomainGetStatsWorkers[i].func; i++) {
> +        if (stats & testDomainGetStatsWorkers[i].stats) {
> +            if (testDomainGetStatsWorkers[i].func(dom, params) < 0)
> +                return -1;
> +        }
> +    }
> +
> +    tmp = g_new0(virDomainStatsRecord, 1);
> +
> +    if (!(tmp->dom = virGetDomain(conn, dom->def->name,
> +                                  dom->def->uuid, dom->def->id)))
> +        return -1;
> +
> +    tmp->nparams = virTypedParamListStealParams(params, &tmp->params);
> +    *record = g_steal_pointer(&tmp);
> +    return 0;
> +}
> +
> +static int
> +testConnectGetAllDomainStats(virConnectPtr conn,
> +                             virDomainPtr *doms,
> +                             unsigned int ndoms,
> +                             unsigned int stats,
> +                             virDomainStatsRecordPtr **retStats,
> +                             unsigned int flags)
> +{
> +    testDriver *driver = conn->privateData;
> +    unsigned int lflags = flags &
> (VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE |
> +                                  
> VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT |
> +                                  
> VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE);
> +
> +    unsigned int supported = VIR_DOMAIN_STATS_STATE;
> +    virDomainObj **vms = NULL;
> +    size_t nvms;
> +    virDomainStatsRecordPtr *tmpstats = NULL;
> +    int nstats = 0;
> +    int ret = -1;
> +    size_t i;
> +
> +    virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE |
> +                  VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT |
> +                  VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE |
> +                  VIR_CONNECT_GET_ALL_DOMAINS_STATS_NOWAIT |
> +                  VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING |
> +                  VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS, -
> 1);
> +
> +    if (!stats) {
> +        stats = supported;
> +    } else if ((flags &
> VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS) &&
> +               (stats & ~supported)) {
> +        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
> +                       _("Stats types bits 0x%x are not supported by
> this daemon"),
> +                       stats & ~supported);
> +        return -1;
> +    }
> +
> +    if (ndoms) {
> +        if (virDomainObjListConvert(driver->domains, conn, doms,
> ndoms, &vms,
> +                                    &nvms, NULL, lflags, true) < 0)
> +            return -1;
> +    } else {
> +        if (virDomainObjListCollect(driver->domains, conn, &vms,
> &nvms,
> +                                    NULL, lflags) < 0)
> +            return -1;
> +    }
> +
> +    tmpstats = g_new0(virDomainStatsRecordPtr, nvms + 1);
> +
> +    for (i = 0; i < nvms; i++) {
> +        virDomainStatsRecordPtr tmp = NULL;
> +        virDomainObj *vm = vms[i];
> +
> +        virObjectLock(vm);
> +
> +        if ((testDomainGetStats(conn, vm, stats, &tmp)) < 0)
> +            goto cleanup;
> +
> +        virObjectUnlock(vm);
> +

I am sorry but I just realized that it should be

        if ((testDomainGetStats(conn, vm, stats, &tmp)) < 0) {
            virObjectUnlock(vm);
            goto cleanup;
        }

        virObjectUnlock(vm);

here, I will fix this in v4.

Thanks,
Luke

> +        if (!tmp)
> +            goto cleanup;
> +
> +        tmpstats[nstats++] = tmp;
> +    }
> +
> +    *retStats = g_steal_pointer(&tmpstats);
> +    ret = nstats;
> +
> + cleanup:
> +    virDomainStatsRecordListFree(tmpstats);
> +    virObjectListFreeCount(vms, nvms);
> +
> +    return ret;
> +}
> +
>  /*
>   * Test driver
>   */
> @@ -9799,6 +9933,7 @@ static virHypervisorDriver testHypervisorDriver =
> {
>      .nodeGetCPUStats = testNodeGetCPUStats, /* 2.3.0 */
>      .nodeGetFreeMemory = testNodeGetFreeMemory, /* 2.3.0 */
>      .nodeGetFreePages = testNodeGetFreePages, /* 2.3.0 */
> +    .connectGetAllDomainStats = testConnectGetAllDomainStats, /* 7.7.0
> */
>      .connectGetCapabilities = testConnectGetCapabilities, /* 0.2.1 */
>      .connectGetSysinfo = testConnectGetSysinfo, /* 2.3.0 */
>      .connectGetType = testConnectGetType, /* 2.3.0 */