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-7.8.0/src/conf/domain_stats.c =================================================================== --- /dev/null +++ libvirt-7.8.0/src/conf/domain_stats.c @@ -0,0 +1,117 @@ +/* + * 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 + * . + */ + +#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(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; +} + +#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(virDomainObj *dom, + virTypedParamList *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++) { + virDomainNetDef *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-7.8.0/src/conf/domain_stats.h =================================================================== --- /dev/null +++ libvirt-7.8.0/src/conf/domain_stats.h @@ -0,0 +1,60 @@ +/* + * 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 + * . + */ +#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(virDomainObj *dom, + virTypedParamList *params); + +int virDomainStatsGetInterface(virDomainObj *dom, + virTypedParamList *params); + +#endif /* __DOMAIN_STATS_H */ Index: libvirt-7.8.0/src/libvirt_private.syms =================================================================== --- libvirt-7.8.0.orig/src/libvirt_private.syms +++ libvirt-7.8.0/src/libvirt_private.syms @@ -763,6 +763,11 @@ virDomainConfNWFilterTeardown; virDomainConfVMNWFilterTeardown; +# conf/domain_stats.h +virDomainStatsGetInterface; +virDomainStatsGetState; + + # conf/domain_validate.h virDomainActualNetDefValidate; virDomainDefValidate; @@ -1939,6 +1944,7 @@ virCgroupGetMemoryUsage; virCgroupGetMemSwapHardLimit; virCgroupGetMemSwapUsage; virCgroupGetPercpuStats; +virCgroupGetStatsCpu; virCgroupHasController; virCgroupHasEmptyTasks; virCgroupKillPainfully; Index: libvirt-7.8.0/src/qemu/qemu_driver.c =================================================================== --- libvirt-7.8.0.orig/src/qemu/qemu_driver.c +++ libvirt-7.8.0/src/qemu/qemu_driver.c @@ -68,6 +68,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" @@ -17323,13 +17324,7 @@ qemuDomainGetStatsState(virQEMUDriver *d virTypedParamList *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); } @@ -17621,25 +17616,11 @@ qemuDomainGetStatsCpuCgroup(virDomainObj virTypedParamList *params) { qemuDomainObjPrivate *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 && 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); } static int @@ -17832,76 +17813,15 @@ qemuDomainGetStatsVcpu(virQEMUDriver *dr 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(virQEMUDriver *driver G_GNUC_UNUSED, virDomainObj *dom, virTypedParamList *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++) { - virDomainNetDef *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-7.8.0/src/util/vircgroup.c =================================================================== --- libvirt-7.8.0.orig/src/util/vircgroup.c +++ libvirt-7.8.0/src/util/vircgroup.c @@ -3036,6 +3036,31 @@ virCgroupGetInode(virCgroup *cgroup) return st.st_ino; } +int +virCgroupGetStatsCpu(virCgroup *cgroup, + virTypedParamList *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 @@ -3045,6 +3070,14 @@ virCgroupAvailable(void) } +int +virCgroupGetStatsCpu(virCgroup *cgroup, + virTypedParamList *params) +{ + return 0; +} + + int virCgroupNewPartition(const char *path G_GNUC_UNUSED, bool create G_GNUC_UNUSED, Index: libvirt-7.8.0/src/util/vircgroup.h =================================================================== --- libvirt-7.8.0.orig/src/util/vircgroup.h +++ libvirt-7.8.0/src/util/vircgroup.h @@ -23,6 +23,7 @@ #include "virbitmap.h" #include "virenum.h" +#include "virtypedparam.h" struct _virCgroup; typedef struct _virCgroup virCgroup; @@ -284,4 +285,7 @@ int virCgroupHasEmptyTasks(virCgroup *cg bool virCgroupControllerAvailable(int controller); +int virCgroupGetStatsCpu(virCgroup *cgroup, + virTypedParamList *params); + int virCgroupGetInode(virCgroup *cgroup); Index: libvirt-7.8.0/src/conf/meson.build =================================================================== --- libvirt-7.8.0.orig/src/conf/meson.build +++ libvirt-7.8.0/src/conf/meson.build @@ -15,6 +15,7 @@ domain_conf_sources = [ 'domain_conf.c', 'domain_nwfilter.c', 'domain_validate.c', + 'domain_stats.c', 'moment_conf.c', 'numa_conf.c', 'snapshot_conf.c',