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-6.0.0/src/conf/domain_stats.c
===================================================================
--- /dev/null
+++ libvirt-6.0.0/src/conf/domain_stats.c
@@ -0,0 +1,119 @@
+/*
+ * 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,
+                       virTypedParamListPtr 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;
+}
+
+#define STATS_ADD_NET_PARAM(params, num, name, value) \
+    if (value >= 0 && \
+        virTypedParamListAddULLong((params), (value), "net.%zu.%s", (num), (name)) < 0) \
+        return -1;
+
+int
+virDomainStatsGetInterface(virDomainObjPtr dom,
+                           virTypedParamListPtr params)
+{
+    size_t i;
+    struct _virDomainInterfaceStats tmp;
+
+    if (!virDomainObjIsActive(dom))
+        return 0;
+
+    if (virTypedParamListAddUInt(params, dom->def->nnets, "net.count") < 0)
+        return -1;
+
+    /* 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);
+
+        if (virTypedParamListAddString(params, net->ifname, "net.%zu.name", i) < 0)
+            return -1;
+
+        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(params, i,
+                            "rx.bytes", tmp.rx_bytes);
+        STATS_ADD_NET_PARAM(params, i,
+                            "rx.pkts", tmp.rx_packets);
+        STATS_ADD_NET_PARAM(params, i,
+                            "rx.errs", tmp.rx_errs);
+        STATS_ADD_NET_PARAM(params, i,
+                            "rx.drop", tmp.rx_drop);
+        STATS_ADD_NET_PARAM(params, i,
+                            "tx.bytes", tmp.tx_bytes);
+        STATS_ADD_NET_PARAM(params, i,
+                            "tx.pkts", tmp.tx_packets);
+        STATS_ADD_NET_PARAM(params, i,
+                            "tx.errs", tmp.tx_errs);
+        STATS_ADD_NET_PARAM(params, i,
+                            "tx.drop", tmp.tx_drop);
+    }
+
+    return 0;
+}
+
+#undef STATS_ADD_NET_PARAM
Index: libvirt-6.0.0/src/conf/domain_stats.h
===================================================================
--- /dev/null
+++ libvirt-6.0.0/src/conf/domain_stats.h
@@ -0,0 +1,62 @@
+/*
+ * 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,
+                           virTypedParamListPtr params);
+
+int virDomainStatsGetInterface(virDomainObjPtr dom,
+                           virTypedParamListPtr params);
+
+#endif /* __DOMAIN_STATS_H */
Index: libvirt-6.0.0/src/libvirt_private.syms
===================================================================
--- libvirt-6.0.0.orig/src/libvirt_private.syms
+++ libvirt-6.0.0/src/libvirt_private.syms
@@ -716,6 +716,9 @@ virDomainConfNWFilterInstantiate;
 virDomainConfNWFilterTeardown;
 virDomainConfVMNWFilterTeardown;
 
+# conf/domain_stats.h
+virDomainStatsGetInterface;
+virDomainStatsGetState;
 
 # conf/interface_conf.h
 virInterfaceDefFormat;
@@ -1697,6 +1700,7 @@ virCgroupGetMemoryUsage;
 virCgroupGetMemSwapHardLimit;
 virCgroupGetMemSwapUsage;
 virCgroupGetPercpuStats;
+virCgroupGetStatsCpu;
 virCgroupHasController;
 virCgroupHasEmptyTasks;
 virCgroupKillPainfully;
Index: libvirt-6.0.0/src/qemu/qemu_driver.c
===================================================================
--- libvirt-6.0.0.orig/src/qemu/qemu_driver.c
+++ libvirt-6.0.0/src/qemu/qemu_driver.c
@@ -67,6 +67,7 @@
 #include "virarptable.h"
 #include "viruuid.h"
 #include "domain_conf.h"
+#include "domain_stats.h"
 #include "domain_audit.h"
 #include "node_device_conf.h"
 #include "virpci.h"
@@ -20584,13 +20585,7 @@ qemuDomainGetStatsState(virQEMUDriverPtr
                         virTypedParamListPtr params,
                         unsigned int privflags G_GNUC_UNUSED)
 {
-    if (virTypedParamListAddInt(params, dom->state.state, "state.state") < 0)
-        return -1;
-
-    if (virTypedParamListAddInt(params, dom->state.reason, "state.reason") < 0)
-        return -1;
-
-    return 0;
+    return virDomainStatsGetState(dom, params);
 }
 
 
@@ -20893,17 +20888,7 @@ qemuDomainGetStatsCpuCgroup(virDomainObj
     if (!priv->cgroup)
         return 0;
 
-    err = virCgroupGetCpuacctUsage(priv->cgroup, &cpu_time);
-    if (!err && virTypedParamListAddULLong(params, cpu_time, "cpu.time") < 0)
-        return -1;
-
-    err = virCgroupGetCpuacctStat(priv->cgroup, &user_time, &sys_time);
-    if (!err && virTypedParamListAddULLong(params, user_time, "cpu.user") < 0)
-        return -1;
-    if (!err && virTypedParamListAddULLong(params, sys_time, "cpu.system") < 0)
-        return -1;
-
-    return 0;
+    return virCgroupGetStatsCpu(priv->cgroup, params);
 }
 
 
@@ -21071,76 +21056,15 @@ qemuDomainGetStatsVcpu(virQEMUDriverPtr
     return ret;
 }
 
-#define QEMU_ADD_NET_PARAM(params, num, name, value) \
-    if (value >= 0 && \
-        virTypedParamListAddULLong((params), (value), "net.%zu.%s", (num), (name)) < 0) \
-        return -1;
-
 static int
 qemuDomainGetStatsInterface(virQEMUDriverPtr driver G_GNUC_UNUSED,
                             virDomainObjPtr dom,
                             virTypedParamListPtr params,
                             unsigned int privflags G_GNUC_UNUSED)
 {
-    size_t i;
-    struct _virDomainInterfaceStats tmp;
-
-    if (!virDomainObjIsActive(dom))
-        return 0;
-
-    if (virTypedParamListAddUInt(params, dom->def->nnets, "net.count") < 0)
-        return -1;
-
-    /* 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);
-
-        if (virTypedParamListAddString(params, net->ifname, "net.%zu.name", i) < 0)
-            return -1;
-
-        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(params, i,
-                           "rx.bytes", tmp.rx_bytes);
-        QEMU_ADD_NET_PARAM(params, i,
-                           "rx.pkts", tmp.rx_packets);
-        QEMU_ADD_NET_PARAM(params, i,
-                           "rx.errs", tmp.rx_errs);
-        QEMU_ADD_NET_PARAM(params, i,
-                           "rx.drop", tmp.rx_drop);
-        QEMU_ADD_NET_PARAM(params, i,
-                           "tx.bytes", tmp.tx_bytes);
-        QEMU_ADD_NET_PARAM(params, i,
-                           "tx.pkts", tmp.tx_packets);
-        QEMU_ADD_NET_PARAM(params, i,
-                           "tx.errs", tmp.tx_errs);
-        QEMU_ADD_NET_PARAM(params, i,
-                           "tx.drop", tmp.tx_drop);
-    }
-
-    return 0;
+    return virDomainStatsGetInterface(dom,params);
 }
 
-#undef QEMU_ADD_NET_PARAM
 
 /* refresh information by opening images on the disk */
 static int
Index: libvirt-6.0.0/src/util/vircgroup.c
===================================================================
--- libvirt-6.0.0.orig/src/util/vircgroup.c
+++ libvirt-6.0.0/src/util/vircgroup.c
@@ -2773,6 +2773,31 @@ virCgroupControllerAvailable(int control
     return ret;
 }
 
+int
+virCgroupGetStatsCpu(virCgroupPtr cgroup,
+                     virTypedParamListPtr params)
+{
+    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 && virTypedParamListAddULLong(params, cpu_time, "cpu.time") < 0)
+        return -1;
+
+    err = virCgroupGetCpuacctStat(cgroup, &user_time, &sys_time);
+    if (!err && virTypedParamListAddULLong(params, user_time, "cpu.user") < 0)
+        return -1;
+    if (!err && virTypedParamListAddULLong(params, sys_time, "cpu.system") < 0)
+        return -1;
+
+    return 0;
+}
+
 #else /* !__linux__ */
 
 bool
@@ -2782,6 +2807,14 @@ virCgroupAvailable(void)
 }
 
 
+int
+virCgroupGetStatsCpu(virCgroupPtr cgroup,
+                     virTypedParamListPtr params)
+{
+    return 0;
+}
+
+
 int
 virCgroupNewPartition(const char *path G_GNUC_UNUSED,
                       bool create G_GNUC_UNUSED,
Index: libvirt-6.0.0/src/util/vircgroup.h
===================================================================
--- libvirt-6.0.0.orig/src/util/vircgroup.h
+++ libvirt-6.0.0/src/util/vircgroup.h
@@ -24,6 +24,7 @@
 #include "virutil.h"
 #include "virbitmap.h"
 #include "virenum.h"
+#include "virtypedparam.h"
 
 struct _virCgroup;
 typedef struct _virCgroup virCgroup;
@@ -285,3 +286,6 @@ int virCgroupSetOwner(virCgroupPtr cgrou
 int virCgroupHasEmptyTasks(virCgroupPtr cgroup, int controller);
 
 bool virCgroupControllerAvailable(int controller);
+
+int virCgroupGetStatsCpu(virCgroupPtr cgroup,
+                         virTypedParamListPtr params);
Index: libvirt-6.0.0/src/conf/Makefile.inc.am
===================================================================
--- libvirt-6.0.0.orig/src/conf/Makefile.inc.am
+++ libvirt-6.0.0/src/conf/Makefile.inc.am
@@ -28,6 +28,8 @@ DOMAIN_CONF_SOURCES = \
 	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/moment_conf.c \
