[libvirt] [PATCHv3 07/10] Add unit test for virCgroupGetBlkioIo*Serviced

Michal Privoznik mprivozn at redhat.com
Thu Feb 6 11:46:16 UTC 2014


On 03.02.2014 18:44, Thorsten Behrens wrote:
> ---
> 
> 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);
>       }

This won't work. If one __lxstat, lstat, __xstat, stat is called over path that does not start with SYSFS_PREFIX, in fact it has not been called with such prefix yet, then the fakedevicedir0 and fakedevicedir1 are NULL and hence strncmp will SIGSEGV:

Program received signal SIGSEGV, Segmentation fault.
__strlen_sse2_pminub () at ../sysdeps/x86_64/multiarch/strlen-sse2-pminub.S:38
38      ../sysdeps/x86_64/multiarch/strlen-sse2-pminub.S: No such file or directory.
(gdb) bt
#0  __strlen_sse2_pminub () at ../sysdeps/x86_64/multiarch/strlen-sse2-pminub.S:38
#1  0x00007ffff7df8f79 in __xstat (ver=1, path=0x6215a0 "/etc/libnl/classid", sb=0x7fffffffd7e0) at vircgroupmock.c:619
#2  0x0000003468625627 in rtnl_tc_read_classid_file () from /usr/lib64/libnl-route-3.so.200
#3  0x0000003468617e99 in ?? () from /usr/lib64/libnl-route-3.so.200
#4  0x000000345e80ec2a in call_init (l=<optimized out>, argc=1, argv=0x7fffffffda38, env=0x7fffffffda48) at dl-init.c:78
#5  0x000000345e80ecfc in _dl_init (main_map=0x345ea231a8, argc=1, argv=0x7fffffffda38, env=0x7fffffffda48) at dl-init.c:127
#6  0x000000345e80152a in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#7  0x0000000000000001 in ?? ()
#8  0x00007fffffffde35 in ?? ()
#9  0x0000000000000000 in ?? ()

(gdb) p fakedevicedir0
$5 = 0x0
(gdb) p fakedevicedir1
$6 = 0x0

Michal




More information about the libvir-list mailing list