lkml.org 
[lkml]   [2015]   [Mar]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH] selftest: add a test case to check how locks are shown in fdinfo
Date
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


\
 
 \ /
  Last update: 2015-03-12 17:41    [W:0.170 / U:1.992 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site