---
Notes to v4:
- share fake disk device path via header file instead of env var
tests/testutilslxc.h | 3 ++
tests/vircgroupmock.c | 98 +++++++++++++++++++++++++++++++++++++-
tests/vircgrouptest.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 228 insertions(+), 2 deletions(-)
diff --git a/tests/testutilslxc.h b/tests/testutilslxc.h
index ee8056f..aa0730e 100644
--- a/tests/testutilslxc.h
+++ b/tests/testutilslxc.h
@@ -1,4 +1,7 @@
#include "capabilities.h"
+# define FAKEDEVDIR0 "/fakedevdir0/bla/fasl"
+# define FAKEDEVDIR1 "/fakedevdir1/bla/fasl"
+
virCapsPtr testLXCCapsInit(void);
diff --git a/tests/vircgroupmock.c b/tests/vircgroupmock.c
index 6542973..d154a4a 100644
--- a/tests/vircgroupmock.c
+++ b/tests/vircgroupmock.c
@@ -30,10 +30,13 @@
# include <fcntl.h>
# include <sys/stat.h>
# include <stdarg.h>
+# include "testutilslxc.h"
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 +46,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;
+const char *fakedevicedir0 = FAKEDEVDIR0;
+const char *fakedevicedir1 = FAKEDEVDIR1;
# define SYSFS_PREFIX "/not/really/sys/fs/cgroup/"
@@ -332,13 +337,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 +397,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);
}
@@ -529,6 +545,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 +576,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..df29531 100644
--- a/tests/vircgrouptest.c
+++ b/tests/vircgrouptest.c
@@ -32,6 +32,7 @@
# include "virerror.h"
# include "virlog.h"
# include "virfile.h"
+# include "testutilslxc.h"
# define VIR_FROM_THIS VIR_FROM_NONE
@@ -529,6 +530,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"
@@ -571,6 +694,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.5