From 6609ed5a377c3beaf8389e870b6851856cee42c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= <cbosdonnat@suse.com>
Date: Thu, 4 Jan 2018 12:04:07 +0100
Subject: [PATCH 1/3] Extract stats functions from the qemu driver

Some of the qemu functions getting statistics can easily be reused in
other drivers. Create a conf/domain_stats.[ch] pair to host some of
them.
---
 src/Makefile.am          |   1 +
 src/conf/domain_stats.c  | 139 +++++++++++++++++++++++++++++++++++++++++
 src/conf/domain_stats.h  |  64 +++++++++++++++++++
 src/libvirt_private.syms |   4 ++
 src/qemu/qemu_driver.c   | 158 +++--------------------------------------------
 src/util/vircgroup.c     |  46 ++++++++++++++
 src/util/vircgroup.h     |   4 ++
 7 files changed, 265 insertions(+), 151 deletions(-)
 create mode 100644 src/conf/domain_stats.c
 create mode 100644 src/conf/domain_stats.h

Index: libvirt-4.0.0/src/Makefile.am
===================================================================
--- libvirt-4.0.0.orig/src/Makefile.am
+++ libvirt-4.0.0/src/Makefile.am
@@ -404,6 +404,7 @@ DOMAIN_CONF_SOURCES = \
 		conf/domain_conf.c conf/domain_conf.h \
 		conf/domain_audit.c conf/domain_audit.h \
 		conf/domain_nwfilter.c conf/domain_nwfilter.h \
+		conf/domain_stats.c conf/domain_stats.h \
 		conf/virsavecookie.c conf/virsavecookie.h \
 		conf/snapshot_conf.c conf/snapshot_conf.h \
 		conf/numa_conf.c conf/numa_conf.h \
Index: libvirt-4.0.0/src/conf/domain_stats.c
===================================================================
--- /dev/null
+++ libvirt-4.0.0/src/conf/domain_stats.c
@@ -0,0 +1,139 @@
+/*
+ * domain_stats.c: domain stats extraction helpers
+ *
+ * Copyright (C) 2006-2016 Red Hat, Inc.
+ * Copyright (C) 2006-2008 Daniel P. Berrange
+ * Copyright (c) 2018 SUSE LINUX Products GmbH, Nuernberg, Germany.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Daniel P. Berrange <berrange@redhat.com>
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include "virlog.h"
+#include "domain_stats.h"
+#include "virtypedparam.h"
+#include "virnetdevtap.h"
+#include "virnetdevopenvswitch.h"
+
+#define VIR_FROM_THIS VIR_FROM_DOMAIN
+
+VIR_LOG_INIT("conf.domain_stats");
+
+int
+virDomainStatsGetState(virDomainObjPtr dom,
+                       virDomainStatsRecordPtr record,
+                       int *maxparams)
+{
+    if (virTypedParamsAddInt(&record->params,
+                             &record->nparams,
+                             maxparams,
+                             "state.state",
+                             dom->state.state) < 0)
+        return -1;
+
+    if (virTypedParamsAddInt(&record->params,
+                             &record->nparams,
+                             maxparams,
+                             "state.reason",
+                             dom->state.reason) < 0)
+        return -1;
+
+    return 0;
+}
+
+#define STATS_ADD_NET_PARAM(record, maxparams, num, name, value) \
+do { \
+    char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
+    snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
+             "net.%zu.%s", num, name); \
+    if (value >= 0 && virTypedParamsAddULLong(&(record)->params, \
+                                              &(record)->nparams, \
+                                              maxparams, \
+                                              param_name, \
+                                              value) < 0) \
+        return -1; \
+} while (0)
+
+int
+virDomainStatsGetInterface(virDomainObjPtr dom,
+                           virDomainStatsRecordPtr record,
+                           int *maxparams)
+{
+    size_t i;
+    struct _virDomainInterfaceStats tmp;
+    int ret = -1;
+
+    if (!virDomainObjIsActive(dom))
+        return 0;
+
+    VIR_DOMAIN_STATS_ADD_COUNT_PARAM(record, maxparams, "net", dom->def->nnets);
+
+    /* Check the path is one of the domain's network interfaces. */
+    for (i = 0; i < dom->def->nnets; i++) {
+        virDomainNetDefPtr net = dom->def->nets[i];
+        virDomainNetType actualType;
+
+        if (!net->ifname)
+            continue;
+
+        memset(&tmp, 0, sizeof(tmp));
+
+        actualType = virDomainNetGetActualType(net);
+
+        VIR_DOMAIN_STATS_ADD_NAME_PARAM(record, maxparams,
+                            "net", "name", i, net->ifname);
+
+        if (actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER) {
+            if (virNetDevOpenvswitchInterfaceStats(net->ifname, &tmp) < 0) {
+                virResetLastError();
+                continue;
+            }
+        } else {
+            if (virNetDevTapInterfaceStats(net->ifname, &tmp,
+                                           !virDomainNetTypeSharesHostView(net)) < 0) {
+                virResetLastError();
+                continue;
+            }
+        }
+
+        STATS_ADD_NET_PARAM(record, maxparams, i,
+                           "rx.bytes", tmp.rx_bytes);
+        STATS_ADD_NET_PARAM(record, maxparams, i,
+                           "rx.pkts", tmp.rx_packets);
+        STATS_ADD_NET_PARAM(record, maxparams, i,
+                           "rx.errs", tmp.rx_errs);
+        STATS_ADD_NET_PARAM(record, maxparams, i,
+                           "rx.drop", tmp.rx_drop);
+        STATS_ADD_NET_PARAM(record, maxparams, i,
+                           "tx.bytes", tmp.tx_bytes);
+        STATS_ADD_NET_PARAM(record, maxparams, i,
+                           "tx.pkts", tmp.tx_packets);
+        STATS_ADD_NET_PARAM(record, maxparams, i,
+                           "tx.errs", tmp.tx_errs);
+        STATS_ADD_NET_PARAM(record, maxparams, i,
+                           "tx.drop", tmp.tx_drop);
+    }
+
+    ret = 0;
+ cleanup:
+    return ret;
+}
+
+#undef STATS_ADD_NET_PARAM
Index: libvirt-4.0.0/src/conf/domain_stats.h
===================================================================
--- /dev/null
+++ libvirt-4.0.0/src/conf/domain_stats.h
@@ -0,0 +1,64 @@
+/*
+ * domain_stats.h: domain stats extraction helpers
+ *
+ * Copyright (C) 2006-2016 Red Hat, Inc.
+ * Copyright (C) 2006-2008 Daniel P. Berrange
+ * Copyright (c) 2018 SUSE LINUX Products GmbH, Nuernberg, Germany.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Daniel P. Berrange <berrange@redhat.com>
+ */
+#ifndef __DOMAIN_STATS_H
+# define __DOMAIN_STATS_H
+
+# include "internal.h"
+# include "domain_conf.h"
+
+
+# define VIR_DOMAIN_STATS_ADD_COUNT_PARAM(record, maxparams, type, count) \
+do { \
+    char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
+    snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, "%s.count", type); \
+    if (virTypedParamsAddUInt(&(record)->params, \
+                              &(record)->nparams, \
+                              maxparams, \
+                              param_name, \
+                              count) < 0) \
+        goto cleanup; \
+} while (0)
+
+# define VIR_DOMAIN_STATS_ADD_NAME_PARAM(record, maxparams, type, subtype, num, name) \
+do { \
+    char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
+    snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
+             "%s.%zu.%s", type, num, subtype); \
+    if (virTypedParamsAddString(&(record)->params, \
+                                &(record)->nparams, \
+                                maxparams, \
+                                param_name, \
+                                name) < 0) \
+        goto cleanup; \
+} while (0)
+
+int virDomainStatsGetState(virDomainObjPtr dom,
+                           virDomainStatsRecordPtr record,
+                           int *maxparams);
+
+int virDomainStatsGetInterface(virDomainObjPtr dom,
+                               virDomainStatsRecordPtr record,
+                               int *maxparams);
+
+#endif /* __DOMAIN_STATS_H */
Index: libvirt-4.0.0/src/libvirt_private.syms
===================================================================
--- libvirt-4.0.0.orig/src/libvirt_private.syms
+++ libvirt-4.0.0/src/libvirt_private.syms
@@ -630,6 +630,9 @@ virDomainConfNWFilterRegister;
 virDomainConfNWFilterTeardown;
 virDomainConfVMNWFilterTeardown;
 
+# conf/domain_stats.h
+virDomainStatsGetInterface;
+virDomainStatsGetState;
 
 # conf/interface_conf.h
 virInterfaceDefFormat;
@@ -1468,6 +1471,7 @@ virCgroupGetMemoryUsage;
 virCgroupGetMemSwapHardLimit;
 virCgroupGetMemSwapUsage;
 virCgroupGetPercpuStats;
+virCgroupGetStatsCpu;
 virCgroupHasController;
 virCgroupHasEmptyTasks;
 virCgroupKill;
Index: libvirt-4.0.0/src/qemu/qemu_driver.c
===================================================================
--- libvirt-4.0.0.orig/src/qemu/qemu_driver.c
+++ libvirt-4.0.0/src/qemu/qemu_driver.c
@@ -72,6 +72,7 @@
 #include "viralloc.h"
 #include "viruuid.h"
 #include "domain_conf.h"
+#include "domain_stats.h"
 #include "domain_audit.h"
 #include "node_device_conf.h"
 #include "virpci.h"
@@ -19388,21 +19389,7 @@ qemuDomainGetStatsState(virQEMUDriverPtr
                         int *maxparams,
                         unsigned int privflags ATTRIBUTE_UNUSED)
 {
-    if (virTypedParamsAddInt(&record->params,
-                             &record->nparams,
-                             maxparams,
-                             "state.state",
-                             dom->state.state) < 0)
-        return -1;
-
-    if (virTypedParamsAddInt(&record->params,
-                             &record->nparams,
-                             maxparams,
-                             "state.reason",
-                             dom->state.reason) < 0)
-        return -1;
-
-    return 0;
+    return virDomainStatsGetState(dom, record, maxparams);
 }
 
 
@@ -19425,37 +19412,7 @@ qemuDomainGetStatsCpu(virQEMUDriverPtr d
                       unsigned int privflags ATTRIBUTE_UNUSED)
 {
     qemuDomainObjPrivatePtr priv = dom->privateData;
-    unsigned long long cpu_time = 0;
-    unsigned long long user_time = 0;
-    unsigned long long sys_time = 0;
-    int err = 0;
-
-    if (!priv->cgroup)
-        return 0;
-
-    err = virCgroupGetCpuacctUsage(priv->cgroup, &cpu_time);
-    if (!err && virTypedParamsAddULLong(&record->params,
-                                        &record->nparams,
-                                        maxparams,
-                                        "cpu.time",
-                                        cpu_time) < 0)
-        return -1;
-
-    err = virCgroupGetCpuacctStat(priv->cgroup, &user_time, &sys_time);
-    if (!err && virTypedParamsAddULLong(&record->params,
-                                        &record->nparams,
-                                        maxparams,
-                                        "cpu.user",
-                                        user_time) < 0)
-        return -1;
-    if (!err && virTypedParamsAddULLong(&record->params,
-                                        &record->nparams,
-                                        maxparams,
-                                        "cpu.system",
-                                        sys_time) < 0)
-        return -1;
-
-    return 0;
+    return virCgroupGetStatsCpu(priv->cgroup, record, maxparams);
 }
 
 static int
@@ -19632,44 +19589,6 @@ qemuDomainGetStatsVcpu(virQEMUDriverPtr
     return ret;
 }
 
-#define QEMU_ADD_COUNT_PARAM(record, maxparams, type, count) \
-do { \
-    char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
-    snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, "%s.count", type); \
-    if (virTypedParamsAddUInt(&(record)->params, \
-                              &(record)->nparams, \
-                              maxparams, \
-                              param_name, \
-                              count) < 0) \
-        goto cleanup; \
-} while (0)
-
-#define QEMU_ADD_NAME_PARAM(record, maxparams, type, subtype, num, name) \
-do { \
-    char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
-    snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
-             "%s.%zu.%s", type, num, subtype); \
-    if (virTypedParamsAddString(&(record)->params, \
-                                &(record)->nparams, \
-                                maxparams, \
-                                param_name, \
-                                name) < 0) \
-        goto cleanup; \
-} while (0)
-
-#define QEMU_ADD_NET_PARAM(record, maxparams, num, name, value) \
-do { \
-    char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
-    snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
-             "net.%zu.%s", num, name); \
-    if (value >= 0 && virTypedParamsAddULLong(&(record)->params, \
-                                              &(record)->nparams, \
-                                              maxparams, \
-                                              param_name, \
-                                              value) < 0) \
-        return -1; \
-} while (0)
-
 static int
 qemuDomainGetStatsInterface(virQEMUDriverPtr driver ATTRIBUTE_UNUSED,
                             virDomainObjPtr dom,
@@ -19677,68 +19596,9 @@ qemuDomainGetStatsInterface(virQEMUDrive
                             int *maxparams,
                             unsigned int privflags ATTRIBUTE_UNUSED)
 {
-    size_t i;
-    struct _virDomainInterfaceStats tmp;
-    int ret = -1;
-
-    if (!virDomainObjIsActive(dom))
-        return 0;
-
-    QEMU_ADD_COUNT_PARAM(record, maxparams, "net", dom->def->nnets);
-
-    /* Check the path is one of the domain's network interfaces. */
-    for (i = 0; i < dom->def->nnets; i++) {
-        virDomainNetDefPtr net = dom->def->nets[i];
-        virDomainNetType actualType;
-
-        if (!net->ifname)
-            continue;
-
-        memset(&tmp, 0, sizeof(tmp));
-
-        actualType = virDomainNetGetActualType(net);
-
-        QEMU_ADD_NAME_PARAM(record, maxparams,
-                            "net", "name", i, net->ifname);
-
-        if (actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER) {
-            if (virNetDevOpenvswitchInterfaceStats(net->ifname, &tmp) < 0) {
-                virResetLastError();
-                continue;
-            }
-        } else {
-            if (virNetDevTapInterfaceStats(net->ifname, &tmp,
-                                           !virDomainNetTypeSharesHostView(net)) < 0) {
-                virResetLastError();
-                continue;
-            }
-        }
-
-        QEMU_ADD_NET_PARAM(record, maxparams, i,
-                           "rx.bytes", tmp.rx_bytes);
-        QEMU_ADD_NET_PARAM(record, maxparams, i,
-                           "rx.pkts", tmp.rx_packets);
-        QEMU_ADD_NET_PARAM(record, maxparams, i,
-                           "rx.errs", tmp.rx_errs);
-        QEMU_ADD_NET_PARAM(record, maxparams, i,
-                           "rx.drop", tmp.rx_drop);
-        QEMU_ADD_NET_PARAM(record, maxparams, i,
-                           "tx.bytes", tmp.tx_bytes);
-        QEMU_ADD_NET_PARAM(record, maxparams, i,
-                           "tx.pkts", tmp.tx_packets);
-        QEMU_ADD_NET_PARAM(record, maxparams, i,
-                           "tx.errs", tmp.tx_errs);
-        QEMU_ADD_NET_PARAM(record, maxparams, i,
-                           "tx.drop", tmp.tx_drop);
-    }
-
-    ret = 0;
- cleanup:
-    return ret;
+    return virDomainStatsGetInterface(dom, record, maxparams);
 }
 
-#undef QEMU_ADD_NET_PARAM
-
 #define QEMU_ADD_BLOCK_PARAM_UI(record, maxparams, num, name, value) \
     do { \
         char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
@@ -19860,10 +19720,10 @@ qemuDomainGetStatsOneBlock(virQEMUDriver
     if (disk->info.alias)
         alias = qemuDomainStorageAlias(disk->info.alias, backing_idx);
 
-    QEMU_ADD_NAME_PARAM(record, maxparams, "block", "name", block_idx,
+    VIR_DOMAIN_STATS_ADD_NAME_PARAM(record, maxparams, "block", "name", block_idx,
                         disk->dst);
     if (virStorageSourceIsLocalStorage(src) && src->path)
-        QEMU_ADD_NAME_PARAM(record, maxparams, "block", "path",
+        VIR_DOMAIN_STATS_ADD_NAME_PARAM(record, maxparams, "block", "path",
                             block_idx, src->path);
     if (backing_idx)
         QEMU_ADD_BLOCK_PARAM_UI(record, maxparams, block_idx, "backingIndex",
@@ -19979,7 +19839,7 @@ qemuDomainGetStatsBlock(virQEMUDriverPtr
      * after the iteration than it is to iterate twice; but we still
      * want count listed first.  */
     count_index = record->nparams;
-    QEMU_ADD_COUNT_PARAM(record, maxparams, "block", 0);
+    VIR_DOMAIN_STATS_ADD_COUNT_PARAM(record, maxparams, "block", 0);
 
     for (i = 0; i < dom->def->ndisks; i++) {
         virDomainDiskDefPtr disk = dom->def->disks[i];
@@ -20013,10 +19873,6 @@ qemuDomainGetStatsBlock(virQEMUDriverPtr
 
 #undef QEMU_ADD_BLOCK_PARAM_ULL
 
-#undef QEMU_ADD_NAME_PARAM
-
-#undef QEMU_ADD_COUNT_PARAM
-
 static int
 qemuDomainGetStatsPerfOneEvent(virPerfPtr perf,
                                virPerfEventType type,
Index: libvirt-4.0.0/src/util/vircgroup.c
===================================================================
--- libvirt-4.0.0.orig/src/util/vircgroup.c
+++ libvirt-4.0.0/src/util/vircgroup.c
@@ -4122,6 +4122,44 @@ virCgroupControllerAvailable(int control
     return ret;
 }
 
+int
+virCgroupGetStatsCpu(virCgroupPtr cgroup,
+                     virDomainStatsRecordPtr record,
+                     int *maxparams)
+{
+    unsigned long long cpu_time = 0;
+    unsigned long long user_time = 0;
+    unsigned long long sys_time = 0;
+    int err = 0;
+
+    if (!cgroup)
+        return 0;
+
+    err = virCgroupGetCpuacctUsage(cgroup, &cpu_time);
+    if (!err && virTypedParamsAddULLong(&record->params,
+                                        &record->nparams,
+                                        maxparams,
+                                        "cpu.time",
+                                        cpu_time) < 0)
+        return -1;
+
+    err = virCgroupGetCpuacctStat(cgroup, &user_time, &sys_time);
+    if (!err && virTypedParamsAddULLong(&record->params,
+                                        &record->nparams,
+                                        maxparams,
+                                        "cpu.user",
+                                        user_time) < 0)
+        return -1;
+    if (!err && virTypedParamsAddULLong(&record->params,
+                                        &record->nparams,
+                                        maxparams,
+                                        "cpu.system",
+                                        sys_time) < 0)
+        return -1;
+
+    return 0;
+}
+
 #else /* !VIR_CGROUP_SUPPORTED */
 
 bool
@@ -4899,6 +4937,14 @@ virCgroupControllerAvailable(int control
 {
     return false;
 }
+
+int
+virCgroupGetStatsCpu(virCgroupPtr cgroup,
+                     virDomainStatsRecordPtr record,
+                     int *maxparams)
+{
+    return 0;
+}
 #endif /* !VIR_CGROUP_SUPPORTED */
 
 
Index: libvirt-4.0.0/src/util/vircgroup.h
===================================================================
--- libvirt-4.0.0.orig/src/util/vircgroup.h
+++ libvirt-4.0.0/src/util/vircgroup.h
@@ -297,4 +297,8 @@ int virCgroupSetOwner(virCgroupPtr cgrou
 int virCgroupHasEmptyTasks(virCgroupPtr cgroup, int controller);
 
 bool virCgroupControllerAvailable(int controller);
+
+int virCgroupGetStatsCpu(virCgroupPtr cgroup,
+                         virDomainStatsRecordPtr record,
+                         int *maxparams);
 #endif /* __VIR_CGROUP_H__ */
