Whamcloud - gitweb
LU-6142 tests: Fix style issues for utime.c
[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.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  */
26 /*
27  * This file is part of Lustre, http://www.lustre.org/
28  * Lustre is a trademark of Sun Microsystems, Inc.
29  *
30  * lustre/tests/utime.c
31  *
32  * Simple test for validating mtime on a file create and set via utime.
33  */
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <fcntl.h>
40 #include <unistd.h>
41 #include <time.h>
42 #include <string.h>
43 #include <utime.h>
44 #include <errno.h>
45
46 void usage(char *prog)
47 {
48         fprintf(stderr, "usage: %s <filename> [-s <filename>]\n", prog);
49         exit(1);
50 }
51
52 int main(int argc, char *argv[])
53 {
54         long before_mknod, after_mknod;
55         const char *prog = argv[0];
56         const char *filename = argv[1];
57         char *secname = NULL;
58         struct utimbuf utb;
59         struct stat st, st2;
60         int rc;
61         int c;
62
63         while ((c = getopt(argc, argv, "s:")) != -1) {
64                 switch (c) {
65                 case 's':
66                         secname = optarg;
67                         break;
68                 default:
69                         usage(argv[0]);
70                 }
71         }
72         if (optind + 1 > argc)
73                 usage(argv[0]);
74
75         /*
76          * Adjust the before time back one second, because the kernel's
77          * CURRENT_TIME (lockless clock reading, used to set inode times)
78          * may drift against the do_gettimeofday() time (TSC-corrected and
79          * locked clock reading, used to return timestamps to user space).
80          * This means that the mknod time could be a second older than the
81          * before time, even for a local filesystem such as ext3.
82          */
83         before_mknod = time(0) - 1;
84         rc = mknod(filename, 0700, S_IFREG);
85         after_mknod = time(0);
86         if (rc && errno != EEXIST) {
87                 fprintf(stderr, "%s: mknod(%s) failed: rc %d: %s\n",
88                         prog, filename, errno, strerror(errno));
89                 return 2;
90         } else if (!rc) {
91                 rc = stat(filename, &st);
92                 if (rc) {
93                         fprintf(stderr, "%s: stat(%s) failed: rc %d: %s\n",
94                                 prog, filename, errno, strerror(errno));
95                         return 3;
96                 }
97
98                 if (st.st_mtime < before_mknod || st.st_mtime > after_mknod) {
99                         fprintf(stderr,
100                                 "%s: bad mknod(%s) times %lu <= %lu <= %lu false\n",
101                                 prog, filename, before_mknod, st.st_mtime,
102                                 after_mknod);
103                         return 4;
104                 }
105
106                 printf("%s: good mknod times %lu%s <= %lu <= %lu for %s\n",
107                        prog, before_mknod,
108                        before_mknod == st.st_mtime ? "*" : "",
109                        st.st_mtime, after_mknod, filename);
110
111                 if (secname) {
112                         sleep(1);
113                         rc = stat(secname, &st2);
114                         if (rc) {
115                                 fprintf(stderr,
116                                         "%s: stat(%s) failed: rc %d: %s\n",
117                                         prog, secname, errno, strerror(errno));
118                                 return 5;
119                         }
120
121                         if (st2.st_mtime < before_mknod ||
122                             st2.st_mtime > after_mknod) {
123                                 fprintf(stderr,
124                                         "%s: bad mknod(%s) times %lu  <= %lu <= %lu false\n",
125                                         prog, filename, before_mknod,
126                                         st2.st_mtime, after_mknod);
127                                 return 6;
128                         }
129
130                         printf("%s: good mknod times %lu%s <= %lu <= %lu for %s\n",
131                                prog, before_mknod,
132                                before_mknod == st.st_mtime ? "*" : "",
133                                st2.st_mtime, after_mknod, secname);
134                 }
135         }
136
137         utb.actime = 200000;
138         utb.modtime = 100000;
139         rc = utime(filename, &utb);
140         if (rc) {
141                 fprintf(stderr, "%s: utime(%s) failed: rc %d: %s\n",
142                         prog, filename, errno, strerror(errno));
143                 return 7;
144         }
145
146         rc = stat(filename, &st);
147         if (rc) {
148                 fprintf(stderr, "%s: second stat(%s) failed: rc %d: %s\n",
149                         prog, filename, errno, strerror(errno));
150                 return 8;
151         }
152
153         if (st.st_mtime != utb.modtime) {
154                 fprintf(stderr, "%s: bad utime mtime(%s) %lu should be %lu\n",
155                         prog, filename, st.st_mtime, utb.modtime);
156                 return 9;
157         }
158
159         if (st.st_atime != utb.actime) {
160                 fprintf(stderr, "%s: bad utime atime(%s) %lu should be %lu\n",
161                         prog, filename, st.st_atime, utb.actime);
162                 return 10;
163         }
164
165         printf("%s: good utime mtimes %lu, atime %lu\n",
166                prog, utb.modtime, utb.actime);
167
168         if (!secname)
169                 return 0;
170
171         /* Checking that times in past get updated on another client. */
172         rc = stat(secname, &st2);
173         if (rc) {
174                 fprintf(stderr, "%s: second stat(%s) failed: rc %d: %s\n",
175                         prog, secname, errno, strerror(errno));
176                 return 12;
177         }
178
179         if (st2.st_mtime != st.st_mtime) {
180                 fprintf(stderr,
181                         "%s: not synced mtime(%s) between clients: %lu should be %lu\n",
182                         prog, secname, st2.st_mtime, st.st_mtime);
183                 return 13;
184         }
185
186         if (st2.st_ctime != st.st_ctime) {
187                 fprintf(stderr,
188                         "%s: not synced ctime(%s) between clients: %lu should be %lu\n",
189                         prog, secname, st2.st_ctime, st.st_ctime);
190                 return 14;
191         }
192
193         printf("%s: updated times for %s\n", prog, secname);
194
195         return 0;
196 }