Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / tests / utime.c
1 /*
2  * Simple test for validating mtime on a file create and set via utime.
3  */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9 #include <unistd.h>
10 #include <time.h>
11 #include <string.h>
12 #include <utime.h>
13 #include <errno.h>
14
15 void usage(char *prog)
16 {
17         fprintf(stderr, "usage: %s <filename> [-s <filename>]\n", prog);
18         exit(1);
19 }
20
21 int main(int argc, char *argv[])
22 {
23         long before_mknod, after_mknod;
24         const char *prog = argv[0];
25         const char *filename = argv[1];
26         char *secname = NULL;
27         struct utimbuf utb;
28         struct stat st, st2;
29         int rc;
30         int c;
31
32         utb.actime = 200000;
33         utb.modtime = 100000;
34
35         while ((c = getopt(argc, argv, "s:")) != -1) {
36                 switch(c) {
37                 case 's':
38                         secname = optarg;
39                         break;
40                 default:
41                         usage(argv[0]);
42                 }
43         }
44         if (optind + 1 > argc)
45                 usage(argv[0]);
46
47         /* Adjust the before time back one second, because the kernel's
48          * CURRENT_TIME (lockless clock reading, used to set inode times)
49          * may drift against the do_gettimeofday() time (TSC-corrected and
50          * locked clock reading, used to return timestamps to user space).
51          * This means that the mknod time could be a second older than the
52          * before time, even for a local filesystem such as ext3.
53          */
54         before_mknod = time(0) - 1;
55         rc = mknod(filename, 0700, S_IFREG);
56         after_mknod = time(0);
57         if (rc && errno != EEXIST) {
58                 fprintf(stderr, "%s: mknod(%s) failed: rc %d: %s\n",
59                         prog, filename, errno, strerror(errno));
60                 return 2;
61         } else if (!rc) {
62                 rc = stat(filename, &st);
63                 if (rc) {
64                         fprintf(stderr, "%s: stat(%s) failed: rc %d: %s\n",
65                                 prog, filename, errno, strerror(errno));
66                         return 3;
67                 }
68
69                 if (st.st_mtime < before_mknod || st.st_mtime > after_mknod) {
70                         fprintf(stderr,
71                                 "%s: bad mknod times %lu <= %lu <= %lu false\n",
72                                 prog, before_mknod, st.st_mtime, after_mknod);
73                         return 4;
74                 }
75
76                 printf("%s: good mknod times %lu%s <= %lu <= %lu for %s\n",
77                        prog, before_mknod, before_mknod == st.st_mtime ? "*":"",
78                        st.st_mtime, after_mknod, filename);
79
80                 if (secname) {
81                         sleep(1);
82                         rc = stat(secname, &st2);
83                         if (rc) {
84                                 fprintf(stderr, "%s: stat(%s) failed: rc %d: "
85                                         "%s\n", prog, secname, errno,
86                                         strerror(errno));
87                                 return 5;
88                         }
89
90                         if (st2.st_mtime < before_mknod || 
91                             st2.st_mtime > after_mknod) {
92                                 fprintf(stderr, "%s: bad mknod times %lu <= %lu"
93                                         " <= %lu false\n", prog, before_mknod,
94                                         st2.st_mtime, after_mknod);
95                                 return 6;
96                         }
97
98                         printf("%s: good mknod times %lu%s <= %lu <= %lu "
99                                "for %s\n", prog, before_mknod, 
100                                before_mknod == st.st_mtime ? "*":"", 
101                                st2.st_mtime, after_mknod, secname);
102                 }
103         }
104
105         /* See above */
106         rc = utime(filename, &utb);
107         if (rc) {
108                 fprintf(stderr, "%s: utime(%s) failed: rc %d: %s\n",
109                         prog, filename, errno, strerror(errno));
110                 return 7;
111         }
112         
113         rc = stat(filename, &st);
114         if (rc) {
115                 fprintf(stderr, "%s: second stat(%s) failed: rc %d: %s\n",
116                         prog, filename, errno, strerror(errno));
117                 return 8;
118         }
119
120         if (st.st_mtime != utb.modtime ) {
121                 fprintf(stderr, "%s: bad utime mtime %lu should be  %lu\n",
122                         prog, st.st_mtime, utb.modtime);
123                 return 9;
124         }
125
126         if (st.st_atime != utb.actime ) {
127                 fprintf(stderr, "%s: bad utime atime %lu should be  %lu\n",
128                         prog, st.st_atime, utb.actime);
129                 return 10;
130         }
131
132         printf("%s: good utime mtimes %lu, atime %lu\n",
133                prog, utb.modtime, utb.actime);
134
135         if (secname == NULL)
136                 return 0;
137         
138         /* Checking that times in past get updated on another client. */
139         rc = stat(secname, &st2);
140         if (rc) {
141                 fprintf(stderr, "%s: second stat(%s) failed: rc %d: %s\n",
142                         prog, secname, errno, strerror(errno));
143                 return 12;
144         }
145
146         if (st2.st_mtime != st.st_mtime) {
147                 fprintf(stderr, "%s: not synced mtime between clients: %lu "
148                         "should be  %lu\n", prog, st2.st_mtime, st.st_mtime);
149                 return 13;
150         }
151
152         if (st2.st_ctime != st.st_ctime) {
153                 fprintf(stderr, "%s: not synced ctime between clients: %lu "
154                         " should be  %lu\n", prog, st2.st_ctime, st.st_ctime);
155                 return 14;
156         }
157         
158         printf("%s: updated times for %s\n", prog, secname);
159         
160         return 0;
161 }