On Thu, Mar 12, 2015 at 02:43:19PM -0600, Shuah Khan wrote: > Hi Andrey, > > Looks good in general. Couple of comments. Thanks. The updated version is attached. > > On 03/12/2015 10:30 AM, Andrey Vagin wrote: > > 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 > > Cc: Shuah Khan > > Signed-off-by: Andrey Vagin > > --- > > 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 > > Please move the new target up to keep the TARGETS list > alphabetically sorted. This helps avoid conflicts as new > tests get added. > > > > > 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 > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#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"); > > Look into using ksft framework for reporting pass/fail conditions. > Please see kselftest.h for the framework. > > > + else { > > + fprintf(stderr, "%s\n", buf); > > + return 1; > > + } > > + > > + free(buf); > > + > > + return 0; > > +} > > > > thanks, > -- Shuah > > -- > Shuah Khan > Sr. Linux Kernel Developer > Open Source Innovation Group > Samsung Research America (Silicon Valley) > shuahkh@osg.samsung.com | (970) 217-8978