--- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list