From 6e11de0a98959885c3f81f6ecc05fdb4bfe08ccd Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Thu, 2 Apr 2009 20:53:23 +0530 Subject: Add pre-run and post-run routines for tests; support mounting and unmounting * Support for mouting and unmounting file systems. This will flush out data for sure -- so the times we collect will reflect the time needed to actually write everything we want to to the disk. * Add pre-run and post-run functions that take care of the common functionality needed by each test run Signed-off-by: Amit Shah --- test-file-zero-alloc-speed.c | 164 ++++++++++++++++++++++++++++--------------- 1 file changed, 106 insertions(+), 58 deletions(-) (limited to 'test-file-zero-alloc-speed.c') diff --git a/test-file-zero-alloc-speed.c b/test-file-zero-alloc-speed.c index 8081c74..fbd8a03 100644 --- a/test-file-zero-alloc-speed.c +++ b/test-file-zero-alloc-speed.c @@ -28,29 +28,79 @@ #include #include #include +#include #include #define GB (1024 * 1024 * 1024) -int do_posix_fallocate(char *name, off_t len) +int pre_test_setup(char *source, char *target, char *fstype, + unsigned long mntflags, char *mntopts, char *name, int *fd) { - int r, fd; - struct timeval tv1, tv2; + int r; + + r = mount(source, target, fstype, mntflags, mntopts); + if (r < 0) { + perror("mount"); + return -1; + } unlink(name); - fd = open(name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); - if (fd < 0) { + *fd = open(name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); + if (*fd < 0) { perror("open"); return -1; } + return 0; +} + +int post_test_cleanup(char *target, int *fd) +{ + int r; + + r = close(*fd); + if (r < 0) + perror("close"); + + r = umount(target); + if (r < 0) + perror("unmount"); + + return r; +} + +void run_test(int (test)(char *, int *, off_t, size_t), + char *source, char *target, char *fstype, unsigned long mntflags, + char *mntopts, char *filename, off_t len, size_t data) +{ + int r, fd; + + r = pre_test_setup(source, target, fstype, mntflags, mntopts, + filename, &fd); + if (r < 0) + goto error_exit; + + (test)(target, &fd, len, data); + return; + +error_exit: + post_test_cleanup(target, &fd); + return; +} + +int do_posix_fallocate(char *target, int *fd, off_t len, size_t data) +{ + int r; + struct timeval tv1, tv2; printf("posix-fallocate run time:\n"); gettimeofday(&tv1, NULL); - r = posix_fallocate(fd, 0, len); - close(fd); + r = posix_fallocate(*fd, 0, len); + post_test_cleanup(target, fd); gettimeofday(&tv2, NULL); - if (r < 0) + if (r < 0) { + printf("posix_fallocate, error %d\n", r); return r; + } printf("\tseconds:microseconds: %llu:%llu\n", tv1.tv_sec, tv1.tv_usec); printf("\tseconds:microseconds: %llu:%llu\n", tv2.tv_sec, tv2.tv_usec); printf("\t(approx %us)\n", tv2.tv_sec - tv1.tv_sec); @@ -58,22 +108,15 @@ int do_posix_fallocate(char *name, off_t len) return 0; } -int do_fallocate(char *name, off_t len) +int do_fallocate(char *target, int *fd, off_t len, size_t data) { - int r, fd; + int r; struct timeval tv1, tv2; - unlink(name); - fd = open(name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); - if (fd < 0) { - perror("open"); - return -1; - } - printf("fallocate run time:\n"); gettimeofday(&tv1, NULL); - r = syscall(__NR_fallocate, fd, 0, len); - close(fd); + r = syscall(__NR_fallocate, *fd, 0, len); + post_test_cleanup(target, fd); gettimeofday(&tv2, NULL); if (r < 0) { perror("fallocate"); @@ -86,24 +129,17 @@ int do_fallocate(char *name, off_t len) return 0; } -int do_mmap(char *name, off_t len) +int do_mmap(char *target, int *fd, off_t len, size_t data) { - int fd; struct timeval tv1, tv2; char *addr; - unlink(name); - fd = open(name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); - if (fd < 0) { - perror("open"); - return -1; - } /* memset has to have the mmap'ed file backed by something on * disk -- bus error otherwise */ - ftruncate(fd, len); + ftruncate(*fd, len); - addr = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + addr = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, *fd, 0); if (addr == MAP_FAILED) { perror("mmap"); return -2; @@ -113,7 +149,7 @@ int do_mmap(char *name, off_t len) gettimeofday(&tv1, NULL); memset(addr, 0, len); munmap(addr, len); - close(fd); + post_test_cleanup(target, fd); gettimeofday(&tv2, NULL); printf("\tseconds:microseconds: %llu:%llu\n", tv1.tv_sec, tv1.tv_usec); @@ -123,9 +159,8 @@ int do_mmap(char *name, off_t len) return 0; } -int do_write_chunks(char *name, off_t len, size_t chunk_size) +int do_write_chunks(char *target, int *fd, off_t len, size_t data) { - int fd; struct timeval tv1, tv2; unsigned long long remain = len; @@ -133,26 +168,19 @@ int do_write_chunks(char *name, off_t len, size_t chunk_size) zeros = calloc(1, len); - unlink(name); - fd = open(name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); - if (fd < 0) { - perror("open"); - return -1; - } - - printf("%llu-sized chunk run time:\n", chunk_size); + printf("%llu-sized chunk run time:\n", data); gettimeofday(&tv1, NULL); while (remain) { - int bytes = chunk_size; + int bytes = data; if (bytes > remain) bytes = remain; - if ((bytes = write(fd, zeros, bytes)) < 0) { + if ((bytes = write(*fd, zeros, bytes)) < 0) { perror("write"); return -2; } remain -= bytes; } - close(fd); + post_test_cleanup(target, fd); gettimeofday(&tv2, NULL); printf("\tseconds:microseconds: %llu:%llu\n", tv1.tv_sec, tv1.tv_usec); @@ -165,32 +193,52 @@ int do_write_chunks(char *name, off_t len, size_t chunk_size) int main(int argc, char **argv) { - char *basename; + char *source, *target, *fstype, *mntopts; char filename[200]; + unsigned long mntflags; + unsigned long long filesize; - if (argc < 2) { - printf("usage: %s base-dir\n", argv[0]); + /* FIXME! use getopt */ + if (argc < 5) { + printf("usage: %s [mntflags] [mntopts]\n", + argv[0]); return -1; } - basename = argv[1]; - - sprintf(filename, "%s/file-pf", basename); - do_posix_fallocate(filename, 1ULL * GB); + filesize = atol(argv[1]) * GB; + source = argv[2]; + target = argv[3]; + fstype = argv[4]; + if (argc > 5) + mntflags = atol(argv[5]); + else + mntflags = 0; + if (argc > 6) + mntopts = argv[6]; + else + mntopts = NULL; + + sprintf(filename, "%s/%s-pf", target, fstype); + run_test(do_posix_fallocate, source, target, fstype, mntflags, mntopts, + filename, filesize, 0); #if 0 - sprintf(filename, "%s/file-pf", basename); - do_fallocate(filename, 1ULL * GB); + sprintf(filename, "%s/%s-fallocate", target, fstype); + run_test(do_fallocate, source, target, fstype, mntflags, mntopts, + filename, filesize, 0); #endif - sprintf(filename, "%s/file-mmap", basename); - do_mmap(filename, 1ULL * GB); + sprintf(filename, "%s/%s-mmap", target, fstype); + run_test(do_mmap, source, target, fstype, mntflags, mntopts, + filename, filesize, 0); - sprintf(filename, "%s/file-chunk4", basename); - do_write_chunks(filename, 1ULL * GB, 4 * 1024); + sprintf(filename, "%s/%s-chunk4k", target, fstype); + run_test(do_write_chunks, source, target, fstype, mntflags, mntopts, + filename, filesize, 4 * 1024); - sprintf(filename, "%s/file-chunk8", basename); - do_write_chunks(filename, 1ULL * GB, 8 * 1024); + sprintf(filename, "%s/%s-chunk8k", target, fstype); + run_test(do_write_chunks, source, target, fstype, mntflags, mntopts, + filename, filesize, 8 * 1024); return 0; } -- cgit