Whamcloud - gitweb
b=16098
[fs/lustre-release.git] / lustre / tests / iopentest2.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <fcntl.h>
40 #include <stdio.h>
41 #include <unistd.h>
42 #include <limits.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <libgen.h>
46 #include <errno.h>
47 #include <sys/wait.h>
48
49 const char *progname;
50 const char usage_fmt[] = "Usage: %s <mountpoint>\n";
51 #define INAME_LEN (PATH_MAX + 1)
52
53 #define CHECK_IT(exp, pstr) \
54 if (!(exp)) { \
55     fprintf(stderr, "%s: at %s:%d: ", progname, __FILE__, __LINE__); \
56     perror((pstr)); \
57     exit(1); \
58 }
59
60 #define CHECK_SNPRINTF(rc, len) \
61     CHECK_IT((rc) > 0 && (rc) <= (len), "snprintf() failed")
62
63 static char *get_iname(char *fname, const char *mtpt)
64 {
65         char *iname;
66         int fd, rc;
67         struct stat buf;
68
69         iname = malloc(INAME_LEN);
70         CHECK_IT(iname, "malloc() failed");
71
72         fd = open(fname, O_CREAT, 0644);
73         if (fd < 0 && errno != EISDIR) {
74                 fprintf(stderr, "%s:%d: open(%s) failed: %s\n", __FILE__,
75                         __LINE__, fname, strerror(errno));
76                 exit(1);
77         }
78
79         if (fd >= 0)
80                 close(fd);
81
82         rc = stat(fname, &buf);
83         if (rc != 0) {
84                 fprintf(stderr, "%s:%d: stat(%s) failed: %s\n", __FILE__,
85                         __LINE__, fname, strerror(errno));
86                 exit(1);
87         }
88
89         rc = snprintf(iname, INAME_LEN,
90                       "%s/__iopen__/%lu", mtpt, (unsigned long)buf.st_ino);
91         CHECK_SNPRINTF(rc, INAME_LEN);
92
93         return iname;
94 }
95
96 int main(int argc, char *argv[])
97 {
98         char *fname, *mtpt, *pname;
99         char *fname_iname, *dir;
100         char *dir_iname = NULL, *foo = NULL, *bar = NULL;
101         int rc, fd, i, thread = 0;
102         int pidlist[10];
103
104         pname = strdup(argv[0]);
105         progname = basename(argv[0]);
106
107         if (argc != 2) {
108                 fprintf(stderr, usage_fmt, progname);
109                 return 1;
110         }
111  
112         for (i = 1; i <= 10; i++) {
113                 rc = fork();
114                 if (rc < 0) {
115                         fprintf(stderr, "error: %s: #%d - %s\n", argv[0], i,
116                                 strerror(rc = errno));
117                         break;
118                 } else if (rc == 0) {
119                         thread = i;
120                         break;
121                 }
122                 printf("%s: thread #%d (PID %d) started\n", argv[0], i, rc);
123                 pidlist[i-1] = rc;
124                 rc = 0;
125         }
126
127         if (thread != 0) {
128                 mtpt  = argv[1];
129                 fname = malloc(INAME_LEN);
130                 CHECK_IT(fname, "malloc() failed");
131
132                 rc = snprintf(fname, INAME_LEN,
133                               "%s/%d", mtpt, getpid());
134                 CHECK_SNPRINTF(rc, INAME_LEN);
135
136                 rc = mkdir(fname, 0644);
137                 if (rc != 0) {
138                         fprintf(stderr, "%s:%d: mkdir(%s) failed: %s\n",
139                                 __FILE__, __LINE__, fname, strerror(errno));
140                         exit(1);
141                 }
142
143                 fname_iname = get_iname(fname, mtpt);
144
145                 dir = malloc(INAME_LEN);
146                 CHECK_IT(dir, "malloc() failed");
147
148                 rc = snprintf(dir, INAME_LEN, "%s/dir", fname_iname);
149                 CHECK_SNPRINTF(rc, INAME_LEN);
150
151                 foo = malloc(INAME_LEN);
152                 CHECK_IT(foo, "malloc() failed");
153
154                 bar = malloc(INAME_LEN);
155                 CHECK_IT(bar, "malloc() failed");
156
157                 for (i = 0; i < 1000; i++) {
158                         rc = mkdir(dir, 0644);
159                         if (rc != 0) {
160                                 fprintf(stderr, "%s:%d: mkdir(%s) failed: %s\n",
161                                         __FILE__, __LINE__, dir,
162                                         strerror(errno));
163                                 exit(1);
164                         }
165
166                         dir_iname = get_iname(dir, mtpt);
167
168                         rc = snprintf(foo, INAME_LEN, "%s/bar", dir_iname);
169                         CHECK_SNPRINTF(rc, INAME_LEN);
170
171                         rc = snprintf(bar, INAME_LEN, "%s/bar", dir_iname);
172                         CHECK_SNPRINTF(rc, INAME_LEN);
173
174                         fd = open(foo, O_CREAT, 0644);
175                         if (fd < 0) {
176                                 fprintf(stderr, "%s:%d: open(%s) failed: %s\n",
177                                         __FILE__, __LINE__, foo,
178                                         strerror(errno));
179                                 exit(1);
180                         }
181                         rc = close(fd);
182                         if (rc != 0) {
183                                 fprintf(stderr, "%s:%d: close() failed: %s\n",
184                                         __FILE__, __LINE__, strerror(errno));
185                                 exit(1);
186                         }
187
188                         rc = rename(foo, bar);
189                         if (rc != 0) {
190                                 fprintf(stderr, "%s:%d: rename(%s, %s) failed: "
191                                         "%s\n", __FILE__, __LINE__, foo, bar,
192                                         strerror(errno));
193                                 exit(1);
194                         }
195
196                         rc = unlink(bar);
197                         if (rc != 0) {
198                                 fprintf(stderr, "%s:%d: unlink(%s) failed: "
199                                         "%s\n", __FILE__, __LINE__, bar,
200                                         strerror(errno));
201                                 exit(1);
202                         }
203                         rc = rmdir(dir);
204                         if (rc != 0) {
205                                 fprintf(stderr, "%s:%d: rmdir(%s) failed: %s\n",
206                                         __FILE__, __LINE__, dir,
207                                         strerror(errno));
208                                 exit(1);
209                         }
210
211                         free(dir_iname);
212                 }
213         } else {
214                         for ( i=0; i<10; i++)
215                                 waitpid(pidlist[i], NULL, 0);
216         }
217         return 0;
218 }