---
Adds another dummy device to push the cgroup parsing code a bit
harder
tests/vircgroupmock.c | 107 +++++++++++++++++++++++++++++++++++++++-
tests/vircgrouptest.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 238 insertions(+), 2 deletions(-)
diff --git a/tests/vircgroupmock.c b/tests/vircgroupmock.c
index 6542973..d772652 100644
--- a/tests/vircgroupmock.c
+++ b/tests/vircgroupmock.c
@@ -34,6 +34,8 @@
static int (*realopen)(const char *path, int flags, ...);
static FILE *(*realfopen)(const char *path, const char *mode);
static int (*realaccess)(const char *path, int mode);
+static int (*realstat)(const char *path, struct stat *sb);
+static int (*real__xstat)(int ver, const char *path, struct stat *sb);
static int (*reallstat)(const char *path, struct stat *sb);
static int (*real__lxstat)(int ver, const char *path, struct stat *sb);
static int (*realmkdir)(const char *path, mode_t mode);
@@ -43,6 +45,8 @@ static int (*realmkdir)(const char *path, mode_t mode);
* vircgroupmock.c:462:22: error: static variable 'fakesysfsdir' is used in an
inline function with external linkage [-Werror,-Wstatic-in-inline]
*/
char *fakesysfsdir;
+char *fakedevicedir0;
+char *fakedevicedir1;
# define SYSFS_PREFIX "/not/really/sys/fs/cgroup/"
@@ -332,13 +336,23 @@ static int make_controller(const char *path, mode_t mode)
"8:0 Write 411440480256\n"
"8:0 Sync 248486822912\n"
"8:0 Async 222495764480\n"
- "8:0 Total 470982587392\n");
+ "8:0 Total 470982587392\n"
+ "9:0 Read 59542107137\n"
+ "9:0 Write 411440480257\n"
+ "9:0 Sync 248486822912\n"
+ "9:0 Async 222495764480\n"
+ "9:0 Total 470982587392\n");
MAKE_FILE("blkio.throttle.io_serviced",
"8:0 Read 4832583\n"
"8:0 Write 36641903\n"
"8:0 Sync 30723171\n"
"8:0 Async 10751315\n"
- "8:0 Total 41474486\n");
+ "8:0 Total 41474486\n"
+ "9:0 Read 4832584\n"
+ "9:0 Write 36641904\n"
+ "9:0 Sync 30723171\n"
+ "9:0 Async 10751315\n"
+ "9:0 Total 41474486\n");
MAKE_FILE("blkio.throttle.read_bps_device", "");
MAKE_FILE("blkio.throttle.read_iops_device", "");
MAKE_FILE("blkio.throttle.write_bps_device", "");
@@ -382,6 +396,7 @@ static void init_syms(void)
LOAD_SYM(fopen);
LOAD_SYM(access);
LOAD_SYM_ALT(lstat, __lxstat);
+ LOAD_SYM_ALT(stat, __xstat);
LOAD_SYM(mkdir);
LOAD_SYM(open);
}
@@ -396,6 +411,16 @@ static void init_sysfs(void)
abort();
}
+ if (!(fakedevicedir0 = getenv("LIBVIRT_FAKE_DEVICE_DIR0"))) {
+ fprintf(stderr, "Missing LIBVIRT_FAKE_DEVICE_DIR0 env variable\n");
+ abort();
+ }
+
+ if (!(fakedevicedir1 = getenv("LIBVIRT_FAKE_DEVICE_DIR1"))) {
+ fprintf(stderr, "Missing LIBVIRT_FAKE_DEVICE_DIR1 env variable\n");
+ abort();
+ }
+
# define MAKE_CONTROLLER(subpath) \
do { \
char *path; \
@@ -529,6 +554,14 @@ int __lxstat(int ver, const char *path, struct stat *sb)
}
ret = real__lxstat(ver, newpath, sb);
free(newpath);
+ } else if (STRPREFIX(path, fakedevicedir0)) {
+ sb->st_mode = S_IFBLK;
+ sb->st_rdev = makedev(8, 0);
+ return 0;
+ } else if (STRPREFIX(path, fakedevicedir1)) {
+ sb->st_mode = S_IFBLK;
+ sb->st_rdev = makedev(9, 0);
+ return 0;
} else {
ret = real__lxstat(ver, path, sb);
}
@@ -552,12 +585,82 @@ int lstat(const char *path, struct stat *sb)
}
ret = reallstat(newpath, sb);
free(newpath);
+ } else if (STRPREFIX(path, fakedevicedir0)) {
+ sb->st_mode = S_IFBLK;
+ sb->st_rdev = makedev(8, 0);
+ return 0;
+ } else if (STRPREFIX(path, fakedevicedir1)) {
+ sb->st_mode = S_IFBLK;
+ sb->st_rdev = makedev(9, 0);
+ return 0;
} else {
ret = reallstat(path, sb);
}
return ret;
}
+int __xstat(int ver, const char *path, struct stat *sb)
+{
+ int ret;
+
+ init_syms();
+
+ if (STRPREFIX(path, SYSFS_PREFIX)) {
+ init_sysfs();
+ char *newpath;
+ if (asprintf(&newpath, "%s/%s",
+ fakesysfsdir,
+ path + strlen(SYSFS_PREFIX)) < 0) {
+ errno = ENOMEM;
+ return -1;
+ }
+ ret = real__xstat(ver, newpath, sb);
+ free(newpath);
+ } else if (STRPREFIX(path, fakedevicedir0)) {
+ sb->st_mode = S_IFBLK;
+ sb->st_rdev = makedev(8, 0);
+ return 0;
+ } else if (STRPREFIX(path, fakedevicedir1)) {
+ sb->st_mode = S_IFBLK;
+ sb->st_rdev = makedev(9, 0);
+ return 0;
+ } else {
+ ret = real__xstat(ver, path, sb);
+ }
+ return ret;
+}
+
+int stat(const char *path, struct stat *sb)
+{
+ int ret;
+
+ init_syms();
+
+ if (STRPREFIX(path, SYSFS_PREFIX)) {
+ init_sysfs();
+ char *newpath;
+ if (asprintf(&newpath, "%s/%s",
+ fakesysfsdir,
+ path + strlen(SYSFS_PREFIX)) < 0) {
+ errno = ENOMEM;
+ return -1;
+ }
+ ret = realstat(newpath, sb);
+ free(newpath);
+ } else if (STRPREFIX(path, fakedevicedir0)) {
+ sb->st_mode = S_IFBLK;
+ sb->st_rdev = makedev(8, 0);
+ return 0;
+ } else if (STRPREFIX(path, fakedevicedir1)) {
+ sb->st_mode = S_IFBLK;
+ sb->st_rdev = makedev(9, 0);
+ return 0;
+ } else {
+ ret = realstat(path, sb);
+ }
+ return ret;
+}
+
int mkdir(const char *path, mode_t mode)
{
int ret;
diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c
index d5ed016..a29cdd2 100644
--- a/tests/vircgrouptest.c
+++ b/tests/vircgrouptest.c
@@ -35,6 +35,9 @@
# define VIR_FROM_THIS VIR_FROM_NONE
+# define FAKEDEVDIR0 "/fakedevdir0/bla/fasl"
+# define FAKEDEVDIR1 "/fakedevdir1/bla/fasl"
+
static int validateCgroup(virCgroupPtr cgroup,
const char *expectPath,
const char **expectMountPoint,
@@ -529,6 +532,128 @@ static int testCgroupAvailable(const void *args)
return 0;
}
+static int testCgroupGetBlkioIoServiced(const void *args ATTRIBUTE_UNUSED)
+{
+ virCgroupPtr cgroup = NULL;
+ size_t i;
+ int rv, ret = -1;
+
+ const long long expected_values[] = {
+ 119084214273,
+ 822880960513,
+ 9665167,
+ 73283807
+ };
+ const char* names[] = {
+ "bytes read",
+ "bytes written",
+ "requests read",
+ "requests written"
+ };
+ long long values[ARRAY_CARDINALITY(expected_values)];
+
+ if ((rv = virCgroupNewPartition("/virtualmachines", true,
+ (1 << VIR_CGROUP_CONTROLLER_BLKIO),
+ &cgroup)) < 0) {
+ fprintf(stderr, "Could not create /virtualmachines cgroup: %d\n",
-rv);
+ goto cleanup;
+ }
+
+ if ((rv = virCgroupGetBlkioIoServiced(cgroup,
+ values, &values[1],
+ &values[2], &values[3])) < 0) {
+ fprintf(stderr, "Could not retrieve BlkioIoServiced for /virtualmachines
cgroup: %d\n", -rv);
+ goto cleanup;
+ }
+
+ for (i = 0; i < ARRAY_CARDINALITY(expected_values); i++) {
+ if (expected_values[i] != values[i]) {
+ fprintf(stderr,
+ "Wrong value for %s from virCgroupBlkioIoServiced (expected
%lld)\n",
+ names[i], expected_values[i]);
+ goto cleanup;
+ }
+ }
+
+ ret = 0;
+
+cleanup:
+ virCgroupFree(&cgroup);
+ return ret;
+}
+
+static int testCgroupGetBlkioIoDeviceServiced(const void *args ATTRIBUTE_UNUSED)
+{
+ virCgroupPtr cgroup = NULL;
+ size_t i;
+ int rv, ret = -1;
+ const long long expected_values0[] = {
+ 59542107136,
+ 411440480256,
+ 4832583,
+ 36641903
+ };
+ const long long expected_values1[] = {
+ 59542107137,
+ 411440480257,
+ 4832584,
+ 36641904
+ };
+ const char* names[] = {
+ "bytes read",
+ "bytes written",
+ "requests read",
+ "requests written"
+ };
+ long long values[ARRAY_CARDINALITY(expected_values0)];
+
+ if ((rv = virCgroupNewPartition("/virtualmachines", true,
+ (1 << VIR_CGROUP_CONTROLLER_BLKIO),
+ &cgroup)) < 0) {
+ fprintf(stderr, "Could not create /virtualmachines cgroup: %d\n",
-rv);
+ goto cleanup;
+ }
+
+ if ((rv = virCgroupGetBlkioIoDeviceServiced(cgroup,
+ FAKEDEVDIR0,
+ values, &values[1],
+ &values[2], &values[3])) < 0)
{
+ fprintf(stderr, "Could not retrieve BlkioIoDeviceServiced for
/virtualmachines cgroup: %d\n", -rv);
+ goto cleanup;
+ }
+
+ for (i = 0; i < ARRAY_CARDINALITY(expected_values0); i++) {
+ if (expected_values0[i] != values[i]) {
+ fprintf(stderr,
+ "Wrong value for %s from virCgroupGetBlkioIoDeviceServiced
(expected %lld)\n",
+ names[i], expected_values0[i]);
+ goto cleanup;
+ }
+ }
+
+ if ((rv = virCgroupGetBlkioIoDeviceServiced(cgroup,
+ FAKEDEVDIR1,
+ values, &values[1],
+ &values[2], &values[3])) < 0)
{
+ fprintf(stderr, "Could not retrieve BlkioIoDeviceServiced for
/virtualmachines cgroup: %d\n", -rv);
+ goto cleanup;
+ }
+
+ for (i = 0; i < ARRAY_CARDINALITY(expected_values1); i++) {
+ if (expected_values1[i] != values[i]) {
+ fprintf(stderr,
+ "Wrong value for %s from virCgroupGetBlkioIoDeviceServiced
(expected %lld)\n",
+ names[i], expected_values1[i]);
+ goto cleanup;
+ }
+ }
+
+ ret = 0;
+
+cleanup:
+ virCgroupFree(&cgroup);
+ return ret;
+}
# define FAKESYSFSDIRTEMPLATE abs_builddir "/fakesysfsdir-XXXXXX"
@@ -549,6 +674,8 @@ mymain(void)
}
setenv("LIBVIRT_FAKE_SYSFS_DIR", fakesysfsdir, 1);
+ setenv("LIBVIRT_FAKE_DEVICE_DIR0", FAKEDEVDIR0, 1);
+ setenv("LIBVIRT_FAKE_DEVICE_DIR1", FAKEDEVDIR1, 1);
if (virtTestRun("New cgroup for self", testCgroupNewForSelf, NULL) < 0)
ret = -1;
@@ -571,6 +698,12 @@ mymain(void)
if (virtTestRun("Cgroup available", testCgroupAvailable, (void*)0x1) <
0)
ret = -1;
+ if (virtTestRun("virCgroupGetBlkioIoServiced works",
testCgroupGetBlkioIoServiced, NULL) < 0)
+ ret = -1;
+
+ if (virtTestRun("virCgroupGetBlkioIoDeviceServiced works",
testCgroupGetBlkioIoDeviceServiced, NULL) < 0)
+ ret = -1;
+
setenv("VIR_CGROUP_MOCK_MODE", "allinone", 1);
if (virtTestRun("New cgroup for self (allinone)",
testCgroupNewForSelfAllInOne, NULL) < 0)
ret = -1;
--
1.8.4