X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Ftests%2Fmmap_sanity.c;h=29955cc83bd73aa44694e3d30caf8963ad80323d;hp=6147071f252b90e082e3d1a0662b2ea4260b36ee;hb=ea766bd959cc2347b223d597b3f8a31e010bed72;hpb=6f6320cc43ec48f72994c02436909b276497c544 diff --git a/lustre/tests/mmap_sanity.c b/lustre/tests/mmap_sanity.c index 6147071..29955cc 100644 --- a/lustre/tests/mmap_sanity.c +++ b/lustre/tests/mmap_sanity.c @@ -1,6 +1,39 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: +/* + * GPL HEADER START + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + * GPL HEADER END */ +/* + * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. + * Use is subject to license terms. + * + * Copyright (c) 2012, Intel Corporation. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * Lustre is a trademark of Sun Microsystems, Inc. + */ + #include #include #include @@ -13,194 +46,66 @@ #include #include #include +#include +#include -char *dir = NULL, *node = NULL, *dir2 = NULL; +char *dir = NULL, *dir2 = NULL; long page_size; char mmap_sanity[256]; - static void usage(void) { - printf("Usage: mmap_sanity -d dir [-n node | -m dir2]\n"); - printf(" dir lustre mount point\n"); - printf(" node another client\n"); - printf(" dir2 another mount point\n"); + printf("Usage: mmap_sanity -d dir [-m dir2] [-e ]\n"); + printf(" -d dir lustre mount point\n"); + printf(" -m dir2 another mount point\n"); + printf(" -e testcases skipped test cases, -e 1 -e 2 to exclude" + " test cases 1 and 2.\n"); exit(127); } -#define MMAP_NOTIFY_PORT 7676 -static int mmap_notify(char *target, char *str, int delay) -{ - unsigned short port = MMAP_NOTIFY_PORT; - int socket_type = SOCK_DGRAM; - struct sockaddr_in server; - struct hostent *hp; - int len, sockfd, rc = 0; - - if (target == NULL) - return 0; - - sockfd = socket(AF_INET, socket_type, 0); - if (sockfd < 0) { - perror("socket()"); - return errno; - } - - if ((hp = gethostbyname(target)) == NULL) { - perror(target); - rc = errno; - goto out_close; - } - - memset(&server,0,sizeof(server)); - memcpy(&(server.sin_addr), hp->h_addr, hp->h_length); - server.sin_family = AF_INET; - server.sin_port = htons(port); - - len = sizeof(server); - if (delay) - sleep(delay); - - rc = sendto(sockfd, str, strlen(str), 0, - (struct sockaddr *)&server, len); - if (rc < 0) { - perror("sendto()"); - rc = errno; - } else - rc = 0; - -out_close: - close(sockfd); - return rc; -} - -static int mmap_wait(char *str, int timeout) -{ - unsigned short port = MMAP_NOTIFY_PORT; - int socket_type = SOCK_DGRAM; - struct sockaddr_in local, from; - char host[256]; - struct hostent *hp; - fd_set rfds; - struct timeval tv; - int sockfd, rc = 0; - - if (dir2 != NULL) - return 0; - - memset(host, 0, sizeof(host)); - if (gethostname(host, sizeof(host))) { - perror("gethostname()"); - return errno; - } - - if ((hp = gethostbyname(host)) == NULL) { - perror(host); - return errno; - } - - local.sin_family = AF_INET; - memcpy(&(local.sin_addr), hp->h_addr, hp->h_length); - local.sin_port = htons(port); - - sockfd = socket(AF_INET, socket_type, 0); - if (sockfd < 0) { - perror("socket()"); - return errno; - } - - rc = bind(sockfd, (struct sockaddr *)&local, sizeof(local)); - if (rc < 0) { - perror("bind()"); - rc = errno; - goto out_close; - } - - FD_ZERO(&rfds); - FD_SET(sockfd, &rfds); - tv.tv_sec = timeout ? timeout : 5; - tv.tv_usec = 0; - - rc = select(sockfd + 1, &rfds, NULL, NULL, &tv); - if (rc) { /* got data */ - char buffer[1024]; - int fromlen =sizeof(from); - - memset(buffer, 0, sizeof(buffer)); - rc = recvfrom(sockfd, buffer, sizeof(buffer), - 0, (struct sockaddr *)&from, - (socklen_t *)&fromlen); - if (rc <= 0) { - perror("recvfrom()"); - rc = errno; - goto out_close; - } - rc = 0; - - if (strncmp(str, buffer, strlen(str)) != 0) { - fprintf(stderr, "expected string mismatch!\n"); - rc = EINVAL; - } - } else { /* timeout */ - fprintf(stderr, "timeout!\n"); - rc = ETIME; - } - -out_close: - close(sockfd); - return rc; -} - static int remote_tst(int tc, char *mnt); -static int mmap_run(char *host, int tc) +static int mmap_run(int tc) { pid_t child; - char nodearg[256], command[256]; int rc = 0; child = fork(); if (child < 0) - return errno; + return -errno; else if (child) return 0; if (dir2 != NULL) { rc = remote_tst(tc, dir2); } else { - sprintf(nodearg, "-w %s", node); - sprintf(command, "%s -d %s -n %s -c %d", - mmap_sanity, dir, host, tc); - rc = execlp("pdsh", "pdsh", "-S", nodearg, command, NULL); - if (rc) - perror("execlp()"); + rc = -EINVAL; + fprintf(stderr, "invalid argument!\n"); } _exit(rc); } -static int mmap_initialize(char *myself, int tc) +static int mmap_initialize(char *myself) { char buf[1024], *file; int fdr, fdw, count, rc = 0; - + page_size = sysconf(_SC_PAGESIZE); if (page_size == -1) { perror("sysconf(_SC_PAGESIZE)"); - return errno; + return -errno; } - if (tc) - return 0; /* copy myself to lustre for another client */ fdr = open(myself, O_RDONLY); if (fdr < 0) { perror(myself); - return EINVAL; + return -EINVAL; } file = strrchr(myself, '/'); if (file == NULL) { fprintf(stderr, "can't get test filename\n"); close(fdr); - return EINVAL; + return -EINVAL; } file++; sprintf(mmap_sanity, "%s/%s", dir, file); @@ -209,20 +114,20 @@ static int mmap_initialize(char *myself, int tc) if (fdw < 0) { perror(mmap_sanity); close(fdr); - return EINVAL; + return -EINVAL; } while ((count = read(fdr, buf, sizeof(buf))) != 0) { int writes; if (count < 0) { perror("read()"); - rc = errno; + rc = -errno; break; } writes = write(fdw, buf, count); if (writes != count) { perror("write()"); - rc = errno; + rc = -errno; break; } } @@ -231,10 +136,8 @@ static int mmap_initialize(char *myself, int tc) return rc; } -static void mmap_finalize(int tc) +static void mmap_finalize() { - if (tc) - return; unlink(mmap_sanity); } @@ -242,38 +145,35 @@ static void mmap_finalize(int tc) static int mmap_tst1(char *mnt) { char *ptr, mmap_file[256]; - int i, j, region, fd, rc = 0; + int region, fd, rc = 0; region = page_size * 10; sprintf(mmap_file, "%s/%s", mnt, "mmap_file1"); - + if (unlink(mmap_file) && errno != ENOENT) { perror("unlink()"); - return errno; + return -errno; } fd = open(mmap_file, O_CREAT|O_RDWR, 0600); if (fd < 0) { perror(mmap_file); - return errno; + return -errno; + } + if (ftruncate(fd, region) < 0) { + perror("ftruncate()"); + rc = -errno; + goto out_close; } - ftruncate(fd, region); ptr = mmap(NULL, region, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { perror("mmap()"); - rc = errno; + rc = -errno; goto out_close; } memset(ptr, 'a', region); - /* mem write then sync */ - for (i = 0; i < 5; i++) { - for (j = 0; j < region; j += page_size) - ptr[j] = i; - sync(); - } - munmap(ptr, region); out_close: close(fd); @@ -291,20 +191,24 @@ static int mmap_tst2(char *mnt) if (unlink(mmap_file) && errno != ENOENT) { perror("unlink()"); - return errno; + return -errno; } fd = open(mmap_file, O_CREAT|O_RDWR, 0600); if (fd < 0) { perror(mmap_file); - return errno; + return -errno; + } + if (ftruncate(fd, page_size) < 0) { + perror("ftruncate()"); + rc = -errno; + goto out_close; } - ftruncate(fd, page_size); ptr = mmap(NULL, page_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); if (ptr == MAP_FAILED) { perror("mmap()"); - rc = errno; + rc = -errno; goto out_close; } memcpy(ptr, "blah", strlen("blah")); @@ -313,71 +217,67 @@ static int mmap_tst2(char *mnt) out_close: close(fd); if (rc) - return rc; + return -rc; fd = open(mmap_file, O_RDONLY); if (fd < 0) { perror(mmap_file); - return errno; + return -errno; } rc = read(fd, buf, sizeof(buf)); if (rc < 0) { perror("read()"); - rc = errno; + rc = -errno; goto out_close; } rc = 0; - + if (strncmp("blah", buf, strlen("blah")) == 0) { fprintf(stderr, "mmap write back with MAP_PRIVATE!\n"); - rc = EFAULT; + rc = -EFAULT; } close(fd); unlink(mmap_file); return rc; } -/* cocurrent mmap operations on two nodes */ +/* concurrent mmap operations on two nodes */ static int mmap_tst3(char *mnt) { - char *ptr, mmap_file[256], host[256]; + char *ptr, mmap_file[256]; int region, fd, rc = 0; region = page_size * 100; sprintf(mmap_file, "%s/%s", mnt, "mmap_file3"); - + if (unlink(mmap_file) && errno != ENOENT) { perror("unlink()"); - return errno; + return -errno; } fd = open(mmap_file, O_CREAT|O_RDWR, 0600); if (fd < 0) { perror(mmap_file); - return errno; + return -errno; + } + if (ftruncate(fd, region) < 0) { + perror("ftruncate()"); + rc = -errno; + goto out_close; } - ftruncate(fd, region); ptr = mmap(NULL, region, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { perror("mmap()"); - rc = errno; + rc = -errno; goto out_close; } - if (gethostname(host, sizeof(host))) { - perror("gethostname()"); - rc = errno; - goto out_unmap; - } - - rc = mmap_run(host, 3); + rc = mmap_run(3); if (rc) goto out_unmap; - - rc = mmap_wait("mmap done", 10); - memset(ptr, 'a', region); + memset(ptr, 'a', region); sleep(2); /* wait for remote test finish */ out_unmap: munmap(ptr, region); @@ -385,7 +285,7 @@ out_close: close(fd); unlink(mmap_file); return rc; -} +} static int remote_tst3(char *mnt) { @@ -398,24 +298,18 @@ static int remote_tst3(char *mnt) fd = open(mmap_file, O_RDWR, 0600); if (fd < 0) { perror(mmap_file); - return errno; + return -errno; } ptr = mmap(NULL, region, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { perror("mmap()"); - rc = errno; + rc = -errno; goto out_close; } memset(ptr, 'b', region); - - rc = mmap_notify(node, "mmap done", 1); - if (rc) - goto out_unmap; - memset(ptr, 'c', region); - -out_unmap: + munmap(ptr, region); out_close: close(fd); @@ -426,7 +320,7 @@ out_close: * client2 write to file_4b from mmap()ed file_4a. */ static int mmap_tst4(char *mnt) { - char *ptr, filea[256], fileb[256], host[256]; + char *ptr, filea[256], fileb[256]; int region, fdr, fdw, rc = 0; region = page_size * 100; @@ -435,55 +329,53 @@ static int mmap_tst4(char *mnt) if (unlink(filea) && errno != ENOENT) { perror("unlink()"); - return errno; + return -errno; } if (unlink(fileb) && errno != ENOENT) { perror("unlink()"); - return errno; + return -errno; } fdr = fdw = -1; fdr = open(fileb, O_CREAT|O_RDWR, 0600); if (fdr < 0) { perror(fileb); - return errno; + return -errno; + } + if (ftruncate(fdr, region) < 0) { + perror("ftruncate()"); + rc = -errno; + goto out_close; } - ftruncate(fdr, region); fdw = open(filea, O_CREAT|O_RDWR, 0600); if (fdw < 0) { perror(filea); - rc = errno; + rc = -errno; + goto out_close; + } + if (ftruncate(fdw, region) < 0) { + perror("ftruncate()"); + rc = -errno; goto out_close; } - ftruncate(fdw, region); - + ptr = mmap(NULL, region, PROT_READ|PROT_WRITE, MAP_SHARED, fdr, 0); if (ptr == MAP_FAILED) { perror("mmap()"); - rc = errno; + rc = -errno; goto out_close; } - if (gethostname(host, sizeof(host))) { - perror("gethostname()"); - rc = errno; - goto out_unmap; - } - - rc = mmap_run(host, 4); - if (rc) - goto out_unmap; - - rc = mmap_wait("mmap done", 10); + rc = mmap_run(4); if (rc) goto out_unmap; - + memset(ptr, '1', region); - + rc = write(fdw, ptr, region); if (rc <= 0) { perror("write()"); - rc = errno; + rc = -errno; } else rc = 0; @@ -513,36 +405,31 @@ static int remote_tst4(char *mnt) fdr = open(filea, O_RDWR, 0600); if (fdr < 0) { perror(filea); - return errno; + return -errno; } fdw = open(fileb, O_RDWR, 0600); if (fdw < 0) { perror(fileb); - rc = errno; + rc = -errno; goto out_close; } ptr = mmap(NULL, region, PROT_READ|PROT_WRITE, MAP_SHARED, fdr, 0); if (ptr == MAP_FAILED) { perror("mmap()"); - rc = errno; + rc = -errno; goto out_close; } - rc = mmap_notify(node, "mmap done", 1); - if (rc) - goto out_unmap; - memset(ptr, '2', region); rc = write(fdw, ptr, region); if (rc <= 0) { perror("write()"); - rc = errno; + rc = -errno; } else rc = 0; - -out_unmap: + munmap(ptr, region); out_close: if (fdr >= 0) @@ -552,100 +439,424 @@ out_close: return rc; } +static int cancel_lru_locks(char *prefix) +{ + char cmd[256], line[1024]; + FILE *file; + pid_t child; + int len = 1024, rc = 0; + + child = fork(); + if (child < 0) + return -errno; + else if (child) { + int status; + rc = waitpid(child, &status, WNOHANG); + if (rc == child) + rc = 0; + return rc; + } + + if (prefix) + sprintf(cmd, + "ls /proc/fs/lustre/ldlm/namespaces/*-%s-*/lru_size", + prefix); + else + sprintf(cmd, "ls /proc/fs/lustre/ldlm/namespaces/*/lru_size"); + + file = popen(cmd, "r"); + if (file == NULL) { + perror("popen()"); + return -errno; + } + + while (fgets(line, len, file)) { + FILE *f; + + if (!strlen(line)) + continue; + /* trim newline character */ + *(line + strlen(line) - 1) = '\0'; + f = fopen(line, "w"); + if (f == NULL) { + perror("fopen()"); + rc = -errno; + break; + } + rc = fwrite("clear", strlen("clear") + 1, 1, f); + if (rc < 1) { + perror("fwrite()"); + rc = -errno; + fclose(f); + break; + } + fclose(f); + } + + pclose(file); + _exit(rc); +} + +/* don't dead lock while read/write file to/from the buffer which + * mmaped to just this file */ +static int mmap_tst5(char *mnt) +{ + char *ptr, mmap_file[256]; + int region, fd, off, rc = 0; + + region = page_size * 40; + off = page_size * 10; + sprintf(mmap_file, "%s/%s", mnt, "mmap_file5"); + + if (unlink(mmap_file) && errno != ENOENT) { + perror("unlink()"); + return -errno; + } + + fd = open(mmap_file, O_CREAT|O_RDWR, 0600); + if (fd < 0) { + perror(mmap_file); + return -errno; + } + if (ftruncate(fd, region) < 0) { + perror("ftruncate()"); + rc = -errno; + goto out_close; + } + + ptr = mmap(NULL, region, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (ptr == MAP_FAILED) { + perror("mmap()"); + rc = -errno; + goto out_close; + } + memset(ptr, 'a', region); + + /* cancel unused locks */ + rc = cancel_lru_locks("osc"); + if (rc) + goto out_unmap; + + /* read/write region of file and buffer should be overlap */ + rc = read(fd, ptr + off, off * 2); + if (rc != off * 2) { + perror("read()"); + rc = -errno; + goto out_unmap; + } + rc = write(fd, ptr + off, off * 2); + if (rc != off * 2) { + perror("write()"); + rc = -errno; + } + rc = 0; +out_unmap: + munmap(ptr, region); +out_close: + close(fd); + unlink(mmap_file); + return rc; +} + +/* mmap write to a file form client1 then mmap read from client2 */ +static int mmap_tst6(char *mnt) +{ + char mmap_file[256], mmap_file2[256]; + char *ptr = NULL, *ptr2 = NULL; + int fd = 0, fd2 = 0, rc = 0; + + sprintf(mmap_file, "%s/%s", mnt, "mmap_file6"); + sprintf(mmap_file2, "%s/%s", dir2, "mmap_file6"); + if (unlink(mmap_file) && errno != ENOENT) { + perror("unlink()"); + return -errno; + } + + fd = open(mmap_file, O_CREAT|O_RDWR, 0600); + if (fd < 0) { + perror(mmap_file); + return -errno; + } + if (ftruncate(fd, page_size) < 0) { + perror("ftruncate()"); + rc = -errno; + goto out; + } + + fd2 = open(mmap_file2, O_RDWR, 0600); + if (fd2 < 0) { + perror(mmap_file2); + rc = -errno; + goto out; + } + + ptr = mmap(NULL, page_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (ptr == MAP_FAILED) { + perror("mmap()"); + rc = -errno; + goto out; + } + + ptr2 = mmap(NULL, page_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd2, 0); + if (ptr2 == MAP_FAILED) { + perror("mmap()"); + rc = -errno; + goto out; + } + + rc = cancel_lru_locks("osc"); + if (rc) + goto out; + + memcpy(ptr, "blah", strlen("blah")); + if (strncmp(ptr, ptr2, strlen("blah"))) { + fprintf(stderr, "client2 mmap mismatch!\n"); + rc = -EFAULT; + goto out; + } + memcpy(ptr2, "foo", strlen("foo")); + if (strncmp(ptr, ptr2, strlen("foo"))) { + fprintf(stderr, "client1 mmap mismatch!\n"); + rc = -EFAULT; + } +out: + if (ptr2) + munmap(ptr2, page_size); + if (ptr) + munmap(ptr, page_size); + if (fd2 > 0) + close(fd2); + if (fd > 0) + close(fd); + unlink(mmap_file); + return rc; +} + +static int mmap_tst7_func(char *mnt, int rw) +{ + char fname[256]; + char *buf = MAP_FAILED; + ssize_t bytes; + int fd = -1; + int rc = 0; + + if (snprintf(fname, 256, "%s/mmap_tst7.%s", mnt, + (rw == 0) ? "read" : "write") >= 256) { + fprintf(stderr, "dir name too long\n"); + rc = -ENAMETOOLONG; + goto out; + } + fd = open(fname, O_RDWR | O_DIRECT | O_CREAT, 0644); + if (fd == -1) { + perror("open"); + rc = -errno; + goto out; + } + if (ftruncate(fd, 2 * page_size) == -1) { + perror("truncate"); + rc = -errno; + goto out; + } + buf = mmap(NULL, page_size * 2, + PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (buf == MAP_FAILED) { + perror("mmap"); + rc = -errno; + goto out; + } + /* ensure the second page isn't mapped */ + munmap(buf + page_size, page_size); + bytes = (rw == 0) ? read(fd, buf, 2 * page_size) : + write(fd, buf, 2 * page_size); + /* Expected behavior */ + if (bytes == page_size) + goto out; + + fprintf(stderr, "%s returned %zd, errno = %d\n", + (rw == 0) ? "read" : "write", bytes, errno); + rc = -EIO; +out: + if (buf != MAP_FAILED) + munmap(buf, page_size); + if (fd != -1) + close(fd); + return rc; +} + +static int mmap_tst7(char *mnt) +{ + int rc; + + rc = mmap_tst7_func(mnt, 0); + if (rc != 0) + return rc; + rc = mmap_tst7_func(mnt, 1); + return rc; +} + +static int mmap_tst8(char *mnt) +{ + char fname[256]; + char *buf = MAP_FAILED; + int fd = -1; + int rc = 0; + pid_t pid; + char xyz[page_size * 2]; + + if (snprintf(fname, 256, "%s/mmap_tst8", mnt) >= 256) { + fprintf(stderr, "dir name too long\n"); + rc = -ENAMETOOLONG; + goto out; + } + fd = open(fname, O_RDWR | O_CREAT, 0644); + if (fd == -1) { + perror("open"); + rc = -errno; + goto out; + } + if (ftruncate(fd, page_size) == -1) { + perror("truncate"); + rc = -errno; + goto out; + } + buf = mmap(NULL, page_size * 2, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (buf == MAP_FAILED) { + perror("mmap"); + rc = -errno; + goto out; + } + + pid = fork(); + if (pid == 0) { /* child */ + memcpy(xyz, buf, page_size * 2); + /* shouldn't reach here. */ + exit(0); + } else if (pid > 0) { /* parent */ + int status = 0; + pid = waitpid(pid, &status, 0); + if (pid < 0) { + perror("wait"); + rc = -errno; + goto out; + } + + rc = -EFAULT; + if (WIFSIGNALED(status) && SIGBUS == WTERMSIG(status)) + rc = 0; + } else { + perror("fork"); + rc = -errno; + } + +out: + if (buf != MAP_FAILED) + munmap(buf, page_size); + if (fd != -1) + close(fd); + return rc; +} + static int remote_tst(int tc, char *mnt) { int rc = 0; - switch(tc) { + switch (tc) { case 3: rc = remote_tst3(mnt); break; case 4: rc = remote_tst4(mnt); break; - case 1: - case 2: default: fprintf(stderr, "wrong test case number %d\n", tc); - rc = EINVAL; + rc = -EINVAL; break; } return rc; } - + struct test_case { int tc; /* test case number */ char *desc; /* test description */ - int (* test_fn)(char *mnt); /* test function */ + int (*test_fn)(char *mnt); /* test function */ int node_cnt; /* node count */ + int skipped; /* skipped by caller */ }; struct test_case tests[] = { { 1, "mmap test1: basic mmap operation", mmap_tst1, 1 }, { 2, "mmap test2: MAP_PRIVATE not write back", mmap_tst2, 1 }, - { 3, "mmap test3: cocurrent mmap ops on two nodes", mmap_tst3, 2 }, - { 4, "mmap test4: c1 write to f1 from mmaped f2, " - "c2 write to f1 from mmaped f1", mmap_tst4, 2 }, + { 3, "mmap test3: concurrent mmap ops on two nodes", mmap_tst3, 2 }, + { 4, "mmap test4: c1 write to f1 from mmapped f2, " + "c2 write to f1 from mmapped f1", mmap_tst4, 2 }, + { 5, "mmap test5: read/write file to/from the buffer " + "which mmapped to just this file", mmap_tst5, 1 }, + { 6, "mmap test6: check mmap write/read content on two nodes", + mmap_tst6, 2 }, + { 7, "mmap test7: file i/o with an unmapped buffer", mmap_tst7, 1}, + { 8, "mmap test8: SIGBUS for beyond file size", mmap_tst8, 1 }, { 0, NULL, 0, 0 } }; int main(int argc, char **argv) { - extern char *optarg; struct test_case *test; - int c, rc = 0, tc = 0; + int nr_cases = sizeof(tests)/sizeof(*test); + int c, rc = 0; - for(;;) { - c = getopt(argc, argv, "d:n:c:m:"); - if ( c == -1 ) + while ((c = getopt(argc, argv, "d:m:e:")) != -1) { + switch (c) { + case 'd': + dir = optarg; break; - - switch(c) { - case 'd': - dir = optarg; - break; - case 'n': - node = optarg; - break; - case 'c': - tc = atoi(optarg); - break; - case 'm': - dir2 = optarg; - break; - default: - case '?': + case 'm': + dir2 = optarg; + break; + case 'e': { + char *endptr = NULL; + rc = strtol(optarg, &endptr, 10); + if (endptr != NULL && *endptr != '\0') usage(); - break; + if (rc > 0 && rc < nr_cases) + tests[rc - 1].skipped = 1; + break; + } + default: + usage(); + break; } } if (dir == NULL) usage(); - if (dir2 != NULL && node != NULL) - usage(); - if (mmap_initialize(argv[0], tc) != 0) { + if (mmap_initialize(argv[0]) != 0) { fprintf(stderr, "mmap_initialize failed!\n"); - return EINVAL; + return -EINVAL; } - if (tc) { - rc = remote_tst(tc, dir); - goto out; - } - + rc = 0; for (test = tests; test->tc; test++) { - char *rs = "skip"; - rc = 0; - if (test->node_cnt == 1 || node != NULL || dir2 != NULL) { + double duration = 0.0; + char *rs = "SKIPPED"; + + if (!test->skipped && (test->node_cnt == 1 || dir2 != NULL)) { + struct timeval start, end; + + gettimeofday(&start, NULL); rc = test->test_fn(dir); - rs = rc ? "fail" : "pass"; + gettimeofday(&end, NULL); + + duration = (double)(end.tv_sec - start.tv_sec) + + (double)(end.tv_usec - start.tv_usec) / 1000000; + rs = rc ? "FAIL" : "PASS"; } - fprintf(stderr, "%s (%s)\n", test->desc, rs); + + fprintf(stderr, "%s (%s, %.5gs)\n", test->desc, rs, duration); if (rc) break; } -out: - mmap_finalize(tc); - return rc; + + mmap_finalize(); + return -rc; }