Whamcloud - gitweb
LU-7931 tests: setup/cleanup after every test script
[fs/lustre-release.git] / lustre / tests / utime.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  */
30 /*
31  * This file is part of Lustre, http://www.lustre.org/
32  * Lustre is a trademark of Sun Microsystems, Inc.
33  *
34  * lustre/tests/utime.c
35  *
36  * Simple test for validating mtime on a file create and set via utime.
37  */
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <fcntl.h>
44 #include <unistd.h>
45 #include <time.h>
46 #include <string.h>
47 #include <utime.h>
48 #include <errno.h>
49
50 void usage(char *prog)
51 {
52         fprintf(stderr, "usage: %s <filename> [-s <filename>]\n", prog);
53         exit(1);
54 }
55
56 int main(int argc, char *argv[])
57 {
58         long before_mknod, after_mknod;
59         const char *prog = argv[0];
60         const char *filename = argv[1];
61         char *secname = NULL;
62         struct utimbuf utb;
63         struct stat st, st2;
64         int rc;
65         int c;
66
67         while ((c = getopt(argc, argv, "s:")) != -1) {
68                 switch(c) {
69                 case 's':
70                         secname = optarg;
71                         break;
72                 default:
73                         usage(argv[0]);
74                 }
75         }
76         if (optind + 1 > argc)
77                 usage(argv[0]);
78
79         /* Adjust the before time back one second, because the kernel's
80          * CURRENT_TIME (lockless clock reading, used to set inode times)
81          * may drift against the do_gettimeofday() time (TSC-corrected and
82          * locked clock reading, used to return timestamps to user space).
83          * This means that the mknod time could be a second older than the
84          * before time, even for a local filesystem such as ext3.
85          */
86         before_mknod = time(0) - 1;
87         rc = mknod(filename, 0700, S_IFREG);
88         after_mknod = time(0);
89         if (rc && errno != EEXIST) {
90                 fprintf(stderr, "%s: mknod(%s) failed: rc %d: %s\n",
91                         prog, filename, errno, strerror(errno));
92                 return 2;
93         } else if (!rc) {
94                 rc = stat(filename, &st);
95                 if (rc) {
96                         fprintf(stderr, "%s: stat(%s) failed: rc %d: %s\n",
97                                 prog, filename, errno, strerror(errno));
98                         return 3;
99                 }
100
101                 if (st.st_mtime < before_mknod || st.st_mtime > after_mknod) {
102                         fprintf(stderr, "%s: bad mknod(%s) times %lu <= %lu <= "
103                                 "%lu false\n", prog, filename, before_mknod,
104                                 st.st_mtime, after_mknod);
105                         return 4;
106                 }
107
108                 printf("%s: good mknod times %lu%s <= %lu <= %lu for %s\n",
109                        prog, before_mknod, before_mknod == st.st_mtime ? "*":"",
110                        st.st_mtime, after_mknod, filename);
111
112                 if (secname) {
113                         sleep(1);
114                         rc = stat(secname, &st2);
115                         if (rc) {
116                                 fprintf(stderr, "%s: stat(%s) failed: rc %d: "
117                                         "%s\n", prog, secname, errno,
118                                         strerror(errno));
119                                 return 5;
120                         }
121
122                         if (st2.st_mtime < before_mknod || 
123                             st2.st_mtime > after_mknod) {
124                                 fprintf(stderr, "%s: bad mknod(%s) times %lu "
125                                         " <= %lu <= %lu false\n", prog,
126                                         filename, before_mknod, st2.st_mtime,
127                                         after_mknod);
128                                 return 6;
129                         }
130
131                         printf("%s: good mknod times %lu%s <= %lu <= %lu "
132                                "for %s\n", prog, before_mknod, 
133                                before_mknod == st.st_mtime ? "*":"", 
134                                st2.st_mtime, after_mknod, secname);
135                 }
136         }
137
138         utb.actime = 200000;
139         utb.modtime = 100000;
140         rc = utime(filename, &utb);
141         if (rc) {
142                 fprintf(stderr, "%s: utime(%s) failed: rc %d: %s\n",
143                         prog, filename, errno, strerror(errno));
144                 return 7;
145         }
146         
147         rc = stat(filename, &st);
148         if (rc) {
149                 fprintf(stderr, "%s: second stat(%s) failed: rc %d: %s\n",
150                         prog, filename, errno, strerror(errno));
151                 return 8;
152         }
153
154         if (st.st_mtime != utb.modtime ) {
155                 fprintf(stderr, "%s: bad utime mtime(%s) %lu should be %lu\n",
156                         prog, filename, st.st_mtime, utb.modtime);
157                 return 9;
158         }
159
160         if (st.st_atime != utb.actime ) {
161                 fprintf(stderr, "%s: bad utime atime(%s) %lu should be %lu\n",
162                         prog, filename, st.st_atime, utb.actime);
163                 return 10;
164         }
165
166         printf("%s: good utime mtimes %lu, atime %lu\n",
167                prog, utb.modtime, utb.actime);
168
169         if (secname == NULL)
170                 return 0;
171         
172         /* Checking that times in past get updated on another client. */
173         rc = stat(secname, &st2);
174         if (rc) {
175                 fprintf(stderr, "%s: second stat(%s) failed: rc %d: %s\n",
176                         prog, secname, errno, strerror(errno));
177                 return 12;
178         }
179
180         if (st2.st_mtime != st.st_mtime) {
181                 fprintf(stderr, "%s: not synced mtime(%s) between clients: "
182                         "%lu should be %lu\n", prog, secname,
183                         st2.st_mtime, st.st_mtime);
184                 return 13;
185         }
186
187         if (st2.st_ctime != st.st_ctime) {
188                 fprintf(stderr, "%s: not synced ctime(%s) between clients: "
189                         "%lu should be %lu\n", prog, secname,
190                         st2.st_ctime, st.st_ctime);
191                 return 14;
192         }
193         
194         printf("%s: updated times for %s\n", prog, secname);
195         
196         return 0;
197 }