[libvirt] [PATCH 3/5 V3] qemu: implement new API virDomainGetPcpusUsage for qemu driver

Lai Jiangshan laijs at cn.fujitsu.com
Wed Jan 18 07:12:10 UTC 2012


Signed-off-by: Lai Jiangshan <laijs at cn.fujitsu.com>
---
 src/qemu/qemu.conf     |    5 ++-
 src/qemu/qemu_conf.c   |    3 +-
 src/qemu/qemu_driver.c |   74 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/util/cgroup.c      |    7 ++++
 src/util/cgroup.h      |    1 +
 5 files changed, 87 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index 4ec5e6c..5f75b3e 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -158,18 +158,19 @@
 #  - 'memory' - use for memory tunables
 #  - 'blkio' - use for block devices I/O tunables
 #  - 'cpuset' - use for CPUs and memory nodes
+#  - 'cpuacct' - use for CPUs' account
 #
 # NB, even if configured here, they won't be used unless
 # the administrator has mounted cgroups, e.g.:
 #
 #  mkdir /dev/cgroup
-#  mount -t cgroup -o devices,cpu,memory,blkio,cpuset none /dev/cgroup
+#  mount -t cgroup -o devices,cpu,memory,blkio,cpuset,cpuacct none /dev/cgroup
 #
 # They can be mounted anywhere, and different controllers
 # can be mounted in different locations. libvirt will detect
 # where they are located.
 #
-# cgroup_controllers = [ "cpu", "devices", "memory", "blkio", "cpuset" ]
+# cgroup_controllers = [ "cpu", "devices", "memory", "blkio", "cpuset", "cpuacct" ]
 
 # This is the basic set of devices allowed / required by
 # all virtual machines.
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index bc0a646..4775638 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -307,7 +307,8 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
             (1 << VIR_CGROUP_CONTROLLER_DEVICES) |
             (1 << VIR_CGROUP_CONTROLLER_MEMORY) |
             (1 << VIR_CGROUP_CONTROLLER_BLKIO) |
-            (1 << VIR_CGROUP_CONTROLLER_CPUSET);
+            (1 << VIR_CGROUP_CONTROLLER_CPUSET) |
+            (1 << VIR_CGROUP_CONTROLLER_CPUACCT);
     }
     for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) {
         if (driver->cgroupControllers & (1 << i)) {
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 712f1fc..e90e185 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -11180,6 +11180,79 @@ cleanup:
     return ret;
 }
 
+static int
+qemuGetPcpusUsage(virDomainPtr dom,
+                  unsigned long long *usages,
+                  int *nr_usages,
+                  unsigned int flags)
+{
+    struct qemud_driver *driver = dom->conn->privateData;
+    virCgroupPtr group = NULL;
+    virDomainObjPtr vm = NULL;
+    char *pos, *raw;
+    unsigned long long val;
+    int nr_cpus = 0;
+    int ret = -1;
+    int rc;
+    bool isActive;
+
+    virCheckFlags(0, -1);
+
+    qemuDriverLock(driver);
+
+    vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+
+    if (vm == NULL) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR,
+                        _("No such domain %s"), dom->uuid);
+        goto cleanup;
+    }
+
+    isActive = virDomainObjIsActive(vm);
+
+    if (!isActive) {
+        qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                        _("domain is not running"));
+        goto cleanup;
+    }
+
+    if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUACCT)) {
+        qemuReportError(VIR_ERR_OPERATION_INVALID,
+                        "%s", _("cgroup CPUACCT controller is not mounted"));
+        goto cleanup;
+    }
+
+    if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR,
+                        _("cannot find cgroup for domain %s"), vm->def->name);
+        goto cleanup;
+    }
+
+    rc = virCgroupGetCpuacctPcpusUsage(group, &raw);
+    if (rc != 0) {
+        virReportSystemError(-rc, "%s", _("unable to get cpu account"));
+        goto cleanup;
+    }
+
+    pos = raw;
+    while (virStrToLong_ull(pos, &pos, 10, &val) >= 0) {
+        if (nr_cpus < *nr_usages) {
+            usages[nr_cpus] = val;
+        }
+        nr_cpus++;
+    }
+
+    VIR_FREE(raw);
+    *nr_usages = nr_cpus;
+    ret = 0;
+
+cleanup:
+    virCgroupFree(&group);
+    if (vm)
+        virDomainObjUnlock(vm);
+    qemuDriverUnlock(driver);
+    return ret;
+}
 
 static virDomainPtr qemuDomainAttach(virConnectPtr conn,
                                      unsigned int pid,
@@ -11983,6 +12056,7 @@ static virDriver qemuDriver = {
     .domainGetNumaParameters = qemuDomainGetNumaParameters, /* 0.9.9 */
     .domainGetInterfaceParameters = qemuDomainGetInterfaceParameters, /* 0.9.9 */
     .domainSetInterfaceParameters = qemuDomainSetInterfaceParameters, /* 0.9.9 */
+    .domainGetPcpusUsage = qemuGetPcpusUsage, /* 0.9.10 */
 };
 
 
diff --git a/src/util/cgroup.c b/src/util/cgroup.c
index 25f2691..114eeb5 100644
--- a/src/util/cgroup.c
+++ b/src/util/cgroup.c
@@ -1554,6 +1554,13 @@ int virCgroupGetCpuacctUsage(virCgroupPtr group, unsigned long long *usage)
                                 "cpuacct.usage", usage);
 }
 
+int virCgroupGetCpuacctPcpusUsage(virCgroupPtr group, char **usage)
+{
+    return virCgroupGetValueStr(group,
+                                VIR_CGROUP_CONTROLLER_CPUACCT,
+                                "cpuacct.usage_percpu", usage);
+}
+
 int virCgroupSetFreezerState(virCgroupPtr group, const char *state)
 {
     return virCgroupSetValueStr(group,
diff --git a/src/util/cgroup.h b/src/util/cgroup.h
index 8d75735..f3c4b7d 100644
--- a/src/util/cgroup.h
+++ b/src/util/cgroup.h
@@ -115,6 +115,7 @@ int virCgroupSetCpuCfsQuota(virCgroupPtr group, long long cfs_quota);
 int virCgroupGetCpuCfsQuota(virCgroupPtr group, long long *cfs_quota);
 
 int virCgroupGetCpuacctUsage(virCgroupPtr group, unsigned long long *usage);
+int virCgroupGetCpuacctPcpusUsage(virCgroupPtr group, char **usage);
 
 int virCgroupSetFreezerState(virCgroupPtr group, const char *state);
 int virCgroupGetFreezerState(virCgroupPtr group, char **state);
-- 
1.7.4.4




More information about the libvir-list mailing list