Messages in this thread Patch in this message | | | From | Andrey Vagin <> | Subject | [PATCH] selftest: add a test case to check how locks are shown in fdinfo | Date | Thu, 12 Mar 2015 19:30:55 +0300 |
| |
The main idea of this test is to check that locks are shown correctly when they can't be placed in a default seq_file buffer due to its size.
Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Shuah Khan <shuahkh@osg.samsung.com> Signed-off-by: Andrey Vagin <avagin@openvz.org> --- tools/testing/selftests/Makefile | 1 + tools/testing/selftests/fdinfo/Makefile | 11 +++ tools/testing/selftests/fdinfo/locks.c | 119 ++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 tools/testing/selftests/fdinfo/Makefile create mode 100644 tools/testing/selftests/fdinfo/locks.c
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 4e51122..8cd57f6 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -17,6 +17,7 @@ TARGETS += sysctl TARGETS += timers TARGETS += user TARGETS += vm +TARGETS += fdinfo #Please keep the TARGETS list alphabetically sorted TARGETS_HOTPLUG = cpu-hotplug diff --git a/tools/testing/selftests/fdinfo/Makefile b/tools/testing/selftests/fdinfo/Makefile new file mode 100644 index 0000000..83f34ef --- /dev/null +++ b/tools/testing/selftests/fdinfo/Makefile @@ -0,0 +1,11 @@ +CFLAGS += -Wall + +all: locks + +run_tests: all + @./locks || echo "locks: [FAIL]" + +locks: locks.c + +clean: + rm -f locks diff --git a/tools/testing/selftests/fdinfo/locks.c b/tools/testing/selftests/fdinfo/locks.c new file mode 100644 index 0000000..93f25c6 --- /dev/null +++ b/tools/testing/selftests/fdinfo/locks.c @@ -0,0 +1,119 @@ +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#define pr_perror(fmt, ...) fprintf(stderr, "%s:%d: " fmt ": %m\n", \ + __FILE__, __LINE__, ##__VA_ARGS__) + +#define FILE_SIZE 4096 + +int main(int argc, char **argv) +{ + int fd, fdinfo, i, ret, size, bsize = 4096; + char *buf, *p, fdinfo_path[] = "/proc/self/fdinfo/XXXXXXXXXX"; + + fd = open("test_file", O_RDWR | O_CREAT, 0666); + if (fd == -1) { + pr_perror("Unable to open test_file"); + return 1; + } + unlink("test_file"); + if (ftruncate(fd, FILE_SIZE) == -1) { + pr_perror("Unable to truncate test_file"); + return 1; + } + + /* + * Generate FILE_SIZE locks. We are going to exceed the default + * size of seq buffer + */ + for (i = 0; i < FILE_SIZE; i++) { + struct flock lock; + + if (i % 2) + lock.l_type = F_WRLCK; + else + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = i; + lock.l_len = 1; + lock.l_pid = -1; + if (fcntl(fd, F_SETLK, &lock)) { + pr_perror("Unable to set lock %d\n", i); + return 1; + } + } + + snprintf(fdinfo_path, sizeof(fdinfo_path), "/proc/self/fdinfo/%d", fd); + fdinfo = open(fdinfo_path, O_RDONLY); + if (fdinfo < 0) { + pr_perror("Unable to open %s", fdinfo_path); + return 1; + } + + buf = malloc(bsize); + if (buf == NULL) { + pr_perror("Unable to allocate a buffer"); + return 1; + } + size = 0; + while (1) { + ret = read(fdinfo, buf + size, bsize - 1 - size); + if (ret == 0) + break; + if (ret == -1) { + pr_perror("Unable to read %s", fdinfo_path); + return 1; + } + size += ret; + if (bsize - size < 4096) + bsize += 4096; + buf = realloc(buf, bsize); + if (buf == NULL) { + pr_perror("Unable to allocate a buffer"); + return 1; + } + } + buf[size] = 0; + + i = 0; + for (p = buf - 1; p != NULL; p = strchr(p, '\n')) { + char fl_flag[10], fl_type[15], fl_option[10], end[32]; + int fl_id, fl_owner, maj, min; + unsigned long ino; + unsigned long long start; + + p++; + + if (strncmp(p, "lock:", 5)) + continue; + ret = sscanf(p, "lock:\t%d:%s %s %s %d %x:%x:%ld %lld %s", + &fl_id, fl_flag, fl_type, fl_option, + &fl_owner, &maj, &min, &ino, + &start, end); + if (ret != 10) { + pr_perror("Unable to parse"); + fprintf(stderr, "%s\n", buf); + return 1; + } + i++; + } + + close(fdinfo); + close(fd); + + if (i == FILE_SIZE) + printf("PASS\n"); + else { + fprintf(stderr, "%s\n", buf); + return 1; + } + + free(buf); + + return 0; +} -- 2.1.0
| |