From 3eabebeb9d795992db6b8f85a3ac36727350bd86 Mon Sep 17 00:00:00 2001
From: Ryota Ozaki <ozaki.ryota@gmail.com>
Date: Thu, 5 Mar 2009 02:09:12 +0900
Subject: [PATCH] lxc: dominfo.cpuTime support using cgroups.cpuacct.usage

This patch enables to get CPU usage of a lxc using cpuacct subsystem
of cgroups.
---
 src/cgroup.c     |    6 ++++++
 src/cgroup.h     |    2 ++
 src/lxc_driver.c |   16 ++++++++++++++--
 3 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/src/cgroup.c b/src/cgroup.c
index 8bd6e87..5af44bd 100644
--- a/src/cgroup.c
+++ b/src/cgroup.c
@@ -38,6 +38,7 @@ struct virCgroup {
 const char *supported_controllers[] = {
     "memory",
     "devices",
+    "cpuacct",
     NULL
 };
 
@@ -797,3 +798,8 @@ int virCgroupGetCpuShares(virCgroupPtr group, unsigned long *shares)
 {
     return virCgroupGetValueU64(group, "cpu.shares", (uint64_t *)shares);
 }
+
+int virCgroupGetCpuacctUsage(virCgroupPtr group, unsigned long long *usage)
+{
+    return virCgroupGetValueU64(group, "cpuacct.usage", (uint64_t *)usage);
+}
diff --git a/src/cgroup.h b/src/cgroup.h
index db68bac..11c44f9 100644
--- a/src/cgroup.h
+++ b/src/cgroup.h
@@ -42,6 +42,8 @@ int virCgroupAllowDeviceMajor(virCgroupPtr group,
 int virCgroupSetCpuShares(virCgroupPtr group, unsigned long shares);
 int virCgroupGetCpuShares(virCgroupPtr group, unsigned long *shares);
 
+int virCgroupGetCpuacctUsage(virCgroupPtr group, unsigned long long *usage);
+
 int virCgroupRemove(virCgroupPtr group);
 
 void virCgroupFree(virCgroupPtr *group);
diff --git a/src/lxc_driver.c b/src/lxc_driver.c
index dff05b6..c08ca9c 100644
--- a/src/lxc_driver.c
+++ b/src/lxc_driver.c
@@ -362,6 +362,7 @@ static int lxcDomainGetInfo(virDomainPtr dom,
 {
     lxc_driver_t *driver = dom->conn->privateData;
     virDomainObjPtr vm;
+    virCgroupPtr cgroup = NULL;
     int ret = -1;
 
     lxcDriverLock(driver);
@@ -376,10 +377,19 @@ static int lxcDomainGetInfo(virDomainPtr dom,
 
     info->state = vm->state;
 
-    if (!virDomainIsActive(vm)) {
+    if (!virDomainIsActive(vm) || virCgroupHaveSupport() != 0) {
         info->cpuTime = 0;
     } else {
-        info->cpuTime = 0;
+        if (virCgroupForDomain(vm->def, "lxc", &cgroup) != 0) {
+            lxcError(dom->conn, dom, VIR_ERR_INTERNAL_ERROR,
+                     _("Unable to get cgroup for %s\n"), vm->def->name);
+            goto cleanup;
+        }
+
+        if (virCgroupGetCpuacctUsage(cgroup, &(info->cpuTime)) < 0) {
+            lxcError(dom->conn, dom, VIR_ERR_OPERATION_FAILED, ("cannot read cputime for domain"));
+            goto cleanup;
+        }
     }
 
     info->maxMem = vm->def->maxmem;
@@ -388,6 +398,8 @@ static int lxcDomainGetInfo(virDomainPtr dom,
     ret = 0;
 
 cleanup:
+    if (cgroup)
+        virCgroupFree(&cgroup);
     if (vm)
         virDomainObjUnlock(vm);
     return ret;
-- 
1.6.0.6

