From 1a2be7098cf5acfd893153abb52b65e69631dcec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= Date: Tue, 2 Jan 2018 14:44:39 +0100 Subject: [PATCH 2/3] lxc: implement connectGetAllDomainStats LXC containers can also provide some statistics. Allow users to fetch them using the existing API. --- src/lxc/lxc_driver.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) Index: libvirt-5.10.0/src/lxc/lxc_driver.c =================================================================== --- libvirt-5.10.0.orig/src/lxc/lxc_driver.c +++ libvirt-5.10.0/src/lxc/lxc_driver.c @@ -75,6 +75,7 @@ #include "viraccessapichecklxc.h" #include "virhostdev.h" #include "netdev_bandwidth_conf.h" +#include "domain_stats.h" #define VIR_FROM_THIS VIR_FROM_LXC @@ -5382,6 +5383,135 @@ lxcDomainHasManagedSaveImage(virDomainPt return ret; } +static int +lxcDomainGetStatsCpu(virDomainObjPtr dom, + virTypedParamListPtr params) +{ + virLXCDomainObjPrivatePtr priv = dom->privateData; + return virCgroupGetStatsCpu(priv->cgroup, params); +} + +typedef int +(*lxcDomainGetStatsFunc)(virDomainObjPtr dom, + virTypedParamListPtr params); + + +struct lxcDomainGetStatsWorker { + lxcDomainGetStatsFunc func; + unsigned int stats; +}; + +static struct lxcDomainGetStatsWorker lxcDomainGetStatsWorkers[] = { + { virDomainStatsGetState, VIR_DOMAIN_STATS_STATE }, + { lxcDomainGetStatsCpu, VIR_DOMAIN_STATS_CPU_TOTAL }, + { virDomainStatsGetInterface, VIR_DOMAIN_STATS_INTERFACE }, + { NULL, 0 } +}; + +static int +lxcDomainGetStats(virConnectPtr conn, + virDomainObjPtr dom, + unsigned int stats, + virDomainStatsRecordPtr *record) +{ + g_autofree virDomainStatsRecordPtr tmp = NULL; + g_autoptr(virTypedParamList) params = NULL; + size_t i; + + if (VIR_ALLOC(params) < 0) + return -1; + + for (i = 0; lxcDomainGetStatsWorkers[i].func; i++) { + if (stats & lxcDomainGetStatsWorkers[i].stats) { + if (lxcDomainGetStatsWorkers[i].func(dom, params) < 0) + return -1; + } + } + + if (VIR_ALLOC(tmp) < 0) + return -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 +lxcConnectGetAllDomainStats(virConnectPtr conn, + virDomainPtr *doms, + unsigned int ndoms, + unsigned int stats, + virDomainStatsRecordPtr **retStats, + unsigned int flags) +{ + virLXCDriverPtr driver = conn->privateData; + virDomainObjPtr *vms = NULL; + virDomainObjPtr vm; + size_t nvms; + virDomainStatsRecordPtr *tmpstats = NULL; + int nstats = 0; + size_t i; + int ret = -1; + unsigned int lflags = flags & (VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE | + VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT | + VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE); + + virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE | + VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT | + VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE, -1); + + if (virConnectGetAllDomainStatsEnsureACL(conn) < 0) + return -1; + + /* TODO Check stats support */ + + if (ndoms) { + if (virDomainObjListConvert(driver->domains, conn, doms, ndoms, &vms, + &nvms, virConnectGetAllDomainStatsCheckACL, + lflags, true) < 0) + return -1; + } else { + if (virDomainObjListCollect(driver->domains, conn, &vms, &nvms, + virConnectGetAllDomainStatsCheckACL, + lflags) < 0) + return -1; + } + + if (VIR_ALLOC_N(tmpstats, nvms + 1) < 0) + return -1; + + for (i = 0; i < nvms; i++) { + virDomainStatsRecordPtr tmp = NULL; + vm = vms[i]; + + virObjectLock(vm); + + if (lxcDomainGetStats(conn, vm, stats, &tmp) < 0) { + virObjectUnlock(vm); + goto cleanup; + } + + if (tmp) + tmpstats[nstats++] = tmp; + + virObjectUnlock(vm); + } + + *retStats = tmpstats; + tmpstats = NULL; + + ret = nstats; + + cleanup: + virDomainStatsRecordListFree(tmpstats); + virObjectListFreeCount(vms, nvms); + + return ret; +} /* Function Tables */ static virHypervisorDriver lxcHypervisorDriver = { @@ -5477,6 +5607,7 @@ static virHypervisorDriver lxcHypervisor .nodeGetFreePages = lxcNodeGetFreePages, /* 1.2.6 */ .nodeAllocPages = lxcNodeAllocPages, /* 1.2.9 */ .domainHasManagedSaveImage = lxcDomainHasManagedSaveImage, /* 1.2.13 */ + .connectGetAllDomainStats = lxcConnectGetAllDomainStats, /* 3.11.0 */ }; static virConnectDriver lxcConnectDriver = {