Implement domainGetCPUStats for lxc driver.

This commit is contained in:
Thorsten Behrens 2014-02-14 18:49:02 +01:00 committed by Michal Privoznik
parent 65158899b7
commit 4b3b2f6ceb
4 changed files with 132 additions and 0 deletions

View File

@ -1032,6 +1032,7 @@ virCgroupGetMemorySoftLimit;
virCgroupGetMemoryUsage; virCgroupGetMemoryUsage;
virCgroupGetMemSwapHardLimit; virCgroupGetMemSwapHardLimit;
virCgroupGetMemSwapUsage; virCgroupGetMemSwapUsage;
virCgroupGetPercpuStats;
virCgroupHasController; virCgroupHasController;
virCgroupIsolateMount; virCgroupIsolateMount;
virCgroupKill; virCgroupKill;

View File

@ -77,6 +77,7 @@
#define LXC_NB_MEM_PARAM 3 #define LXC_NB_MEM_PARAM 3
static int lxcStateInitialize(bool privileged, static int lxcStateInitialize(bool privileged,
virStateInhibitCallback callback, virStateInhibitCallback callback,
void *opaque); void *opaque);
@ -5420,6 +5421,53 @@ cleanup:
} }
static int
lxcDomainGetCPUStats(virDomainPtr dom,
virTypedParameterPtr params,
unsigned int nparams,
int start_cpu,
unsigned int ncpus,
unsigned int flags)
{
virDomainObjPtr vm = NULL;
int ret = -1;
virLXCDomainObjPrivatePtr priv;
virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1);
if (!(vm = lxcDomObjFromDomain(dom)))
return ret;
priv = vm->privateData;
if (virDomainGetCPUStatsEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
if (!virDomainObjIsActive(vm)) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("domain is not running"));
goto cleanup;
}
if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUACCT)) {
virReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("cgroup CPUACCT controller is not mounted"));
goto cleanup;
}
if (start_cpu == -1)
ret = virCgroupGetDomainTotalCpuStats(priv->cgroup,
params, nparams);
else
ret = virCgroupGetPercpuStats(priv->cgroup, params,
nparams, start_cpu, ncpus);
cleanup:
if (vm)
virObjectUnlock(vm);
return ret;
}
/* Function Tables */ /* Function Tables */
static virDriver lxcDriver = { static virDriver lxcDriver = {
.no = VIR_DRV_LXC, .no = VIR_DRV_LXC,
@ -5499,6 +5547,7 @@ static virDriver lxcDriver = {
.nodeSuspendForDuration = lxcNodeSuspendForDuration, /* 0.9.8 */ .nodeSuspendForDuration = lxcNodeSuspendForDuration, /* 0.9.8 */
.domainSetMetadata = lxcDomainSetMetadata, /* 1.1.3 */ .domainSetMetadata = lxcDomainSetMetadata, /* 1.1.3 */
.domainGetMetadata = lxcDomainGetMetadata, /* 1.1.3 */ .domainGetMetadata = lxcDomainGetMetadata, /* 1.1.3 */
.domainGetCPUStats = lxcDomainGetCPUStats, /* 1.2.2 */
.nodeGetMemoryParameters = lxcNodeGetMemoryParameters, /* 0.10.2 */ .nodeGetMemoryParameters = lxcNodeGetMemoryParameters, /* 0.10.2 */
.nodeSetMemoryParameters = lxcNodeSetMemoryParameters, /* 0.10.2 */ .nodeSetMemoryParameters = lxcNodeSetMemoryParameters, /* 0.10.2 */
.domainSendProcessSignal = lxcDomainSendProcessSignal, /* 1.0.1 */ .domainSendProcessSignal = lxcDomainSendProcessSignal, /* 1.0.1 */

View File

@ -53,11 +53,14 @@
#include "virsystemd.h" #include "virsystemd.h"
#include "virtypedparam.h" #include "virtypedparam.h"
#include "nodeinfo.h"
#define CGROUP_MAX_VAL 512 #define CGROUP_MAX_VAL 512
#define VIR_FROM_THIS VIR_FROM_CGROUP #define VIR_FROM_THIS VIR_FROM_CGROUP
#define CGROUP_NB_TOTAL_CPU_STAT_PARAM 3 #define CGROUP_NB_TOTAL_CPU_STAT_PARAM 3
#define CGROUP_NB_PER_CPU_STAT_PARAM 1
#if defined(__linux__) && defined(HAVE_GETMNTENT_R) && \ #if defined(__linux__) && defined(HAVE_GETMNTENT_R) && \
defined(_DIRENT_HAVE_D_TYPE) && defined(_SC_CLK_TCK) defined(_DIRENT_HAVE_D_TYPE) && defined(_SC_CLK_TCK)
@ -2824,6 +2827,78 @@ virCgroupDenyDevicePath(virCgroupPtr group, const char *path, int perms)
} }
int
virCgroupGetPercpuStats(virCgroupPtr group,
virTypedParameterPtr params,
unsigned int nparams,
int start_cpu,
unsigned int ncpus)
{
int rv = -1;
size_t i;
int id, max_id;
char *pos;
char *buf = NULL;
virTypedParameterPtr ent;
int param_idx;
unsigned long long cpu_time;
/* return the number of supported params */
if (nparams == 0 && ncpus != 0)
return CGROUP_NB_PER_CPU_STAT_PARAM;
/* To parse account file, we need to know how many cpus are present. */
max_id = nodeGetCPUCount();
if (max_id < 0)
return rv;
if (ncpus == 0) { /* returns max cpu ID */
rv = max_id;
goto cleanup;
}
if (start_cpu > max_id) {
virReportError(VIR_ERR_INVALID_ARG,
_("start_cpu %d larger than maximum of %d"),
start_cpu, max_id);
goto cleanup;
}
/* we get percpu cputime accounting info. */
if (virCgroupGetCpuacctPercpuUsage(group, &buf))
goto cleanup;
pos = buf;
/* return percpu cputime in index 0 */
param_idx = 0;
/* number of cpus to compute */
if (start_cpu >= max_id - ncpus)
id = max_id - 1;
else
id = start_cpu + ncpus - 1;
for (i = 0; i <= id; i++) {
if (virStrToLong_ull(pos, &pos, 10, &cpu_time) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cpuacct parse error"));
goto cleanup;
}
if (i < start_cpu)
continue;
ent = &params[(i - start_cpu) * nparams + param_idx];
if (virTypedParameterAssign(ent, VIR_DOMAIN_CPU_STATS_CPUTIME,
VIR_TYPED_PARAM_ULLONG, cpu_time) < 0)
goto cleanup;
}
rv = nparams;
cleanup:
VIR_FREE(buf);
return rv;
}
int int
virCgroupGetDomainTotalCpuStats(virCgroupPtr group, virCgroupGetDomainTotalCpuStats(virCgroupPtr group,

View File

@ -201,6 +201,13 @@ int virCgroupDenyDevicePath(virCgroupPtr group,
const char *path, const char *path,
int perms); int perms);
int
virCgroupGetPercpuStats(virCgroupPtr group,
virTypedParameterPtr params,
unsigned int nparams,
int start_cpu,
unsigned int ncpus);
int int
virCgroupGetDomainTotalCpuStats(virCgroupPtr group, virCgroupGetDomainTotalCpuStats(virCgroupPtr group,
virTypedParameterPtr params, virTypedParameterPtr params,