This new internal API checks if given CGroup controller is
available. It is going to be needed later when we need to make a
decision whether pin domain memory onto NUMA nodes using cpuset
CGroup controller or using numa_set_membind().
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/vircgroup.c | 19 +++++++++++++++++++
src/util/vircgroup.h | 1 +
tests/vircgrouptest.c | 31 +++++++++++++++++++++++++++++++
4 files changed, 52 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 5716ece..136036b 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1129,6 +1129,7 @@ virCgroupAllowDevice;
virCgroupAllowDeviceMajor;
virCgroupAllowDevicePath;
virCgroupAvailable;
+virCgroupControllerAvailable;
virCgroupControllerTypeFromString;
virCgroupControllerTypeToString;
virCgroupDenyAllDevices;
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index d42f433..00c0bab 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -4011,6 +4011,20 @@ virCgroupHasEmptyTasks(virCgroupPtr cgroup, int controller)
return ret;
}
+bool
+virCgroupControllerAvailable(int controller)
+{
+ virCgroupPtr cgroup;
+ bool ret = false;
+
+ if (virCgroupNewSelf(&cgroup) < 0)
+ return ret;
+
+ ret = virCgroupHasController(cgroup, controller);
+ virCgroupFree(&cgroup);
+ return ret;
+}
+
#else /* !VIR_CGROUP_SUPPORTED */
bool
@@ -4781,4 +4795,9 @@ virCgroupHasEmptyTasks(virCgroupPtr cgroup ATTRIBUTE_UNUSED,
return -1;
}
+bool
+virCgroupControllerAvailable(int controller ATTRIBUTE_UNUSED)
+{
+ return false;
+}
#endif /* !VIR_CGROUP_SUPPORTED */
diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h
index eee15ca..5d6356d 100644
--- a/src/util/vircgroup.h
+++ b/src/util/vircgroup.h
@@ -282,4 +282,5 @@ int virCgroupSetOwner(virCgroupPtr cgroup,
int virCgroupHasEmptyTasks(virCgroupPtr cgroup, int controller);
+bool virCgroupControllerAvailable(int controller);
#endif /* __VIR_CGROUP_H__ */
diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c
index bbf28d1..2b30258 100644
--- a/tests/vircgrouptest.c
+++ b/tests/vircgrouptest.c
@@ -586,6 +586,34 @@ static int testCgroupAvailable(const void *args)
return 0;
}
+static int testCgroupControllerAvailable(const void *args ATTRIBUTE_UNUSED)
+{
+ int ret = 0;
+
+# define CHECK_CONTROLLER(c, present) \
+ if ((present && !virCgroupControllerAvailable(c)) || \
+ (!present && virCgroupControllerAvailable(c))) { \
+ fprintf(stderr, present ? \
+ "Expected controller %s not available\n" : \
+ "Unexpected controller %s available\n", #c); \
+ ret = -1; \
+ }
+
+ CHECK_CONTROLLER(VIR_CGROUP_CONTROLLER_CPU, true)
+ CHECK_CONTROLLER(VIR_CGROUP_CONTROLLER_CPUACCT, true)
+ CHECK_CONTROLLER(VIR_CGROUP_CONTROLLER_CPUSET, true)
+ CHECK_CONTROLLER(VIR_CGROUP_CONTROLLER_MEMORY, true)
+ CHECK_CONTROLLER(VIR_CGROUP_CONTROLLER_DEVICES, false)
+ CHECK_CONTROLLER(VIR_CGROUP_CONTROLLER_FREEZER, true)
+ CHECK_CONTROLLER(VIR_CGROUP_CONTROLLER_BLKIO, true)
+ CHECK_CONTROLLER(VIR_CGROUP_CONTROLLER_NET_CLS, false)
+ CHECK_CONTROLLER(VIR_CGROUP_CONTROLLER_PERF_EVENT, false)
+ CHECK_CONTROLLER(VIR_CGROUP_CONTROLLER_SYSTEMD, true)
+
+# undef CHECK_CONTROLLER
+ return ret;
+}
+
static int testCgroupGetPercpuStats(const void *args ATTRIBUTE_UNUSED)
{
virCgroupPtr cgroup = NULL;
@@ -886,6 +914,9 @@ mymain(void)
if (virtTestRun("Cgroup available", testCgroupAvailable, (void*)0x1) <
0)
ret = -1;
+ if (virtTestRun("Cgroup controller available",
testCgroupControllerAvailable, NULL) < 0)
+ ret = -1;
+
if (virtTestRun("virCgroupGetBlkioIoServiced works",
testCgroupGetBlkioIoServiced, NULL) < 0)
ret = -1;
--
2.0.5