X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Ftests%2Futime.c;h=84e13d3ec50bbf55ba4185c9e8389b9c317628ea;hb=c0fa0ba4a8efcd774f1fe27986a0217c76dedf6d;hp=b59cc6c53d01adb6d9765eec8f2a02d37d8fe460;hpb=067c526a4e5592095a3335478ec2580535ed2be4;p=fs%2Flustre-release.git diff --git a/lustre/tests/utime.c b/lustre/tests/utime.c index b59cc6c..84e13d3 100644 --- a/lustre/tests/utime.c +++ b/lustre/tests/utime.c @@ -1,6 +1,37 @@ /* + * 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.gnu.org/licenses/gpl-2.0.html + * + * GPL HEADER END + */ +/* + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Use is subject to license terms. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * Lustre is a trademark of Sun Microsystems, Inc. + * + * lustre/tests/utime.c + * * Simple test for validating mtime on a file create and set via utime. */ + #include #include #include @@ -10,74 +41,153 @@ #include #include #include +#include void usage(char *prog) { - fprintf(stderr, "usage: %s \n", prog); + fprintf(stderr, "usage: %s [-s ]\n", prog); exit(1); } int main(int argc, char *argv[]) { long before_mknod, after_mknod; - long before_utime, after_utime; - struct stat st; + const char *prog = argv[0]; + const char *filename = argv[1]; + char *secname = NULL; + struct utimbuf utb; + struct stat st, st2; int rc; + int c; - if (argc != 2) + while ((c = getopt(argc, argv, "s:")) != -1) { + switch(c) { + case 's': + secname = optarg; + break; + default: + usage(argv[0]); + } + } + if (optind + 1 > argc) usage(argv[0]); - before_mknod = time(0); - rc = mknod(argv[1], 0700, S_IFREG); + /* Adjust the before time back one second, because the kernel's + * CURRENT_TIME (lockless clock reading, used to set inode times) + * may drift against the do_gettimeofday() time (TSC-corrected and + * locked clock reading, used to return timestamps to user space). + * This means that the mknod time could be a second older than the + * before time, even for a local filesystem such as ext3. + */ + before_mknod = time(0) - 1; + rc = mknod(filename, 0700, S_IFREG); after_mknod = time(0); - if (rc) { + if (rc && errno != EEXIST) { fprintf(stderr, "%s: mknod(%s) failed: rc %d: %s\n", - argv[0], argv[1], rc, strerror(rc)); + prog, filename, errno, strerror(errno)); return 2; - } + } else if (!rc) { + rc = stat(filename, &st); + if (rc) { + fprintf(stderr, "%s: stat(%s) failed: rc %d: %s\n", + prog, filename, errno, strerror(errno)); + return 3; + } - rc = stat(argv[1], &st); - if (rc) { - fprintf(stderr, "%s: stat(%s) failed: rc %d: %s\n", - argv[0], argv[1], rc, strerror(rc)); - return 3; - } + if (st.st_mtime < before_mknod || st.st_mtime > after_mknod) { + fprintf(stderr, "%s: bad mknod(%s) times %lu <= %lu <= " + "%lu false\n", prog, filename, before_mknod, + st.st_mtime, after_mknod); + return 4; + } - if (st.st_mtime < before_mknod || st.st_mtime > after_mknod) { - fprintf(stderr, "%s: bad mknod times %lu <= %lu <= %lu false\n", - argv[0], before_mknod, st.st_mtime, after_mknod); - return 4; - } + printf("%s: good mknod times %lu%s <= %lu <= %lu for %s\n", + prog, before_mknod, before_mknod == st.st_mtime ? "*":"", + st.st_mtime, after_mknod, filename); - printf("%s: good mknod times %lu <= %lu <= %lu\n", - argv[0], before_mknod, st.st_mtime, after_mknod); + if (secname) { + sleep(1); + rc = stat(secname, &st2); + if (rc) { + fprintf(stderr, "%s: stat(%s) failed: rc %d: " + "%s\n", prog, secname, errno, + strerror(errno)); + return 5; + } - sleep(5); + if (st2.st_mtime < before_mknod || + st2.st_mtime > after_mknod) { + fprintf(stderr, "%s: bad mknod(%s) times %lu " + " <= %lu <= %lu false\n", prog, + filename, before_mknod, st2.st_mtime, + after_mknod); + return 6; + } - before_utime = time(0); - rc = utime(argv[0], NULL); - after_utime = time(0); - if (rc) { - fprintf(stderr, "%s: stat(%s) failed: rc %d: %s\n", - argv[0], argv[1], rc, strerror(rc)); - return 5; + printf("%s: good mknod times %lu%s <= %lu <= %lu " + "for %s\n", prog, before_mknod, + before_mknod == st.st_mtime ? "*":"", + st2.st_mtime, after_mknod, secname); + } } - rc = stat(argv[1], &st); + utb.actime = 200000; + utb.modtime = 100000; + rc = utime(filename, &utb); + if (rc) { + fprintf(stderr, "%s: utime(%s) failed: rc %d: %s\n", + prog, filename, errno, strerror(errno)); + return 7; + } + + rc = stat(filename, &st); if (rc) { fprintf(stderr, "%s: second stat(%s) failed: rc %d: %s\n", - argv[0], argv[1], rc, strerror(rc)); - return 6; + prog, filename, errno, strerror(errno)); + return 8; } - if (st.st_mtime < before_utime || st.st_mtime > after_utime) { - fprintf(stderr, "%s: bad utime times %lu <= %lu <= %lu false\n", - argv[0], before_utime, st.st_mtime, after_utime); - return 7; + if (st.st_mtime != utb.modtime ) { + fprintf(stderr, "%s: bad utime mtime(%s) %lu should be %lu\n", + prog, filename, st.st_mtime, utb.modtime); + return 9; } - printf("%s: good utime times %lu <= %lu <= %lu\n", - argv[0], before_mknod, st.st_mtime, after_mknod); + if (st.st_atime != utb.actime ) { + fprintf(stderr, "%s: bad utime atime(%s) %lu should be %lu\n", + prog, filename, st.st_atime, utb.actime); + return 10; + } + + printf("%s: good utime mtimes %lu, atime %lu\n", + prog, utb.modtime, utb.actime); + if (secname == NULL) + return 0; + + /* Checking that times in past get updated on another client. */ + rc = stat(secname, &st2); + if (rc) { + fprintf(stderr, "%s: second stat(%s) failed: rc %d: %s\n", + prog, secname, errno, strerror(errno)); + return 12; + } + + if (st2.st_mtime != st.st_mtime) { + fprintf(stderr, "%s: not synced mtime(%s) between clients: " + "%lu should be %lu\n", prog, secname, + st2.st_mtime, st.st_mtime); + return 13; + } + + if (st2.st_ctime != st.st_ctime) { + fprintf(stderr, "%s: not synced ctime(%s) between clients: " + "%lu should be %lu\n", prog, secname, + st2.st_ctime, st.st_ctime); + return 14; + } + + printf("%s: updated times for %s\n", prog, secname); + return 0; }