From 6609ed5a377c3beaf8389e870b6851856cee42c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= 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.4.0/src/conf/domain_stats.c =================================================================== --- /dev/null +++ libvirt-6.4.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 + * . + * + * Author: Daniel P. Berrange + */ + +#include + +#include + +#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.4.0/src/conf/domain_stats.h =================================================================== --- /dev/null +++ libvirt-6.4.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 + * . + * + * Author: Daniel P. Berrange + */ +#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.4.0/src/libvirt_private.syms =================================================================== --- libvirt-6.4.0.orig/src/libvirt_private.syms +++ libvirt-6.4.0/src/libvirt_private.syms @@ -732,6 +732,9 @@ virDomainConfNWFilterInstantiate; virDomainConfNWFilterTeardown; virDomainConfVMNWFilterTeardown; +# conf/domain_stats.h +virDomainStatsGetInterface; +virDomainStatsGetState; # conf/interface_conf.h virInterfaceDefFormat; @@ -1763,6 +1766,7 @@ virCgroupGetMemoryUsage; virCgroupGetMemSwapHardLimit; virCgroupGetMemSwapUsage; virCgroupGetPercpuStats; +virCgroupGetStatsCpu; virCgroupHasController; virCgroupHasEmptyTasks; virCgroupKillPainfully; Index: libvirt-6.4.0/src/qemu/qemu_driver.c =================================================================== --- libvirt-6.4.0.orig/src/qemu/qemu_driver.c +++ libvirt-6.4.0/src/qemu/qemu_driver.c @@ -64,6 +64,7 @@ #include "virarptable.h" #include "viruuid.h" #include "domain_conf.h" +#include "domain_stats.h" #include "domain_audit.h" #include "domain_cgroup.h" #include "domain_driver.h" @@ -20654,13 +20655,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); } @@ -20963,17 +20958,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); } @@ -21141,76 +21126,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.4.0/src/util/vircgroup.c =================================================================== --- libvirt-6.4.0.orig/src/util/vircgroup.c +++ libvirt-6.4.0/src/util/vircgroup.c @@ -2776,6 +2776,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 @@ -2785,6 +2810,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.4.0/src/util/vircgroup.h =================================================================== --- libvirt-6.4.0.orig/src/util/vircgroup.h +++ libvirt-6.4.0/src/util/vircgroup.h @@ -23,6 +23,7 @@ #include "virbitmap.h" #include "virenum.h" +#include "virtypedparam.h" struct _virCgroup; typedef struct _virCgroup virCgroup; @@ -271,3 +272,6 @@ int virCgroupSetOwner(virCgroupPtr cgrou int virCgroupHasEmptyTasks(virCgroupPtr cgroup, int controller); bool virCgroupControllerAvailable(int controller); + +int virCgroupGetStatsCpu(virCgroupPtr cgroup, + virTypedParamListPtr params); Index: libvirt-6.4.0/src/conf/Makefile.inc.am =================================================================== --- libvirt-6.4.0.orig/src/conf/Makefile.inc.am +++ libvirt-6.4.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 \