Whamcloud - gitweb
Land b1_8_gate onto b1_8 (20081218_1708)
[fs/lustre-release.git] / lustre / liblustre / tests / test_common.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/stat.h>
38 #include <sys/types.h>
39 #include <unistd.h>
40 #include <stdlib.h>
41 #include <stdio.h>
42 #include <fcntl.h>
43 #include <string.h>
44 #include <errno.h>
45 #include <dirent.h>
46 #include <utime.h>
47 #include <stdarg.h>
48
49 #include "test_common.h"
50
51 int exit_on_err = 1;
52
53 /******************************************************************
54  * util functions
55  ******************************************************************/
56
57 #define EXIT(err)                                       \
58         do {                                            \
59                 if (exit_on_err)                        \
60                         exit(err);                      \
61         } while (0)
62
63 #define EXIT_RET(err)                                   \
64         do {                                            \
65                 if (exit_on_err)                        \
66                         exit(err);                      \
67                 else                                    \
68                         return (err);                   \
69         } while (0)
70
71
72 void t_touch(const char *path)
73 {
74         int fd, rc;
75
76         fd = open(path, O_RDWR|O_CREAT, 0644);
77         if (fd < 0) {
78                 printf("open(%s) error: %s\n", path, strerror(errno));
79                 EXIT(fd);
80         }
81
82         rc = close(fd);
83         if (rc) {
84                 printf("close(%s) error: %s\n", path, strerror(errno));
85                 EXIT(rc);
86         }
87 }
88
89 /* XXX Now libsysio don't support mcreate */
90 void t_create(const char *path)
91 {
92         return t_touch(path);
93 #if 0
94         int rc;
95
96         rc = mknod(path, S_IFREG | 0644, 0);
97         if (rc) {
98                 printf("mknod(%s) error: %s\n", path, strerror(errno));
99                 exit(-1);
100         }
101 #endif
102 }
103
104 void t_link(const char *src, const char *dst)
105 {
106         int rc;
107
108         rc = link(src, dst);
109         if (rc) {
110                 printf("link(%s -> %s) error: %s\n", src, dst, strerror(errno));
111                 EXIT(1);
112         }
113 }
114
115 void t_unlink(const char *path)
116 {
117         int rc;
118
119         rc = unlink(path);
120         if (rc) {
121                 printf("unlink(%s) error: %s\n", path, strerror(errno));
122                 EXIT(-1);
123         }
124 }
125
126 void t_mkdir(const char *path)
127 {
128         int rc;
129
130         rc = mkdir(path, 00755);
131         if (rc < 0) {
132                 printf("mkdir(%s) error: %s\n", path, strerror(errno));
133                 EXIT(1);
134         }
135 }
136
137 void t_rmdir(const char *path)
138 {
139         int rc;
140
141         rc = rmdir(path);
142         if (rc) {
143                 printf("rmdir(%s) error: %s\n", path, strerror(errno));
144                 EXIT(1);
145         }
146 }
147
148 void t_symlink(const char *src, const char *new)
149 {
150         int rc;
151
152         rc = symlink(src, new);
153         if (rc) {
154                 printf("symlink(%s<-%s) error: %s\n", src, new, strerror(errno));
155                 EXIT(1);
156         }
157 }
158
159 #define MKDEV(a,b) (((a) << 8) | (b))
160 void t_mknod(const char *path, mode_t mode, int major, int minor)
161 {
162         int rc;
163
164         rc = mknod(path, mode, MKDEV(5, 4));
165         if (rc) {
166                 printf("mknod(%s) error: %s\n", path, strerror(errno));
167                 EXIT(1);
168         }
169 }
170
171 void t_chmod_raw(const char *path, mode_t mode)
172 {
173         int rc;
174         
175         rc = chmod(path, mode);
176         if (rc) {
177                 printf("chmod(%s) error: %s\n", path, strerror(errno));
178                 EXIT(1);
179         }
180 }
181
182 void t_chmod(const char *path, const char *format, ...)
183 {
184 }
185
186 void t_rename(const char *oldpath, const char *newpath)
187 {
188         int rc;
189
190         rc = rename(oldpath, newpath);
191         if (rc) {
192                 printf("rename(%s -> %s) error: %s\n",
193                        oldpath, newpath, strerror(errno));
194                 EXIT(1);
195         }
196 }
197
198 int t_open_readonly(const char *path)
199 {
200         int fd;
201
202         fd = open(path, O_RDONLY);
203         if (fd < 0) {
204                 printf("open(%s) error: %s\n", path, strerror(errno));
205                 EXIT_RET(fd);
206         }
207         return fd;
208 }
209
210 int t_open(const char *path)
211 {
212         int fd;
213
214         fd = open(path, O_RDWR | O_LARGEFILE);
215         if (fd < 0) {
216                 printf("open(%s) error: %s\n", path, strerror(errno));
217                 EXIT_RET(fd);
218         }
219         return fd;
220 }
221
222 int t_chdir(const char *path)
223 {
224         int rc = chdir(path);
225         if (rc < 0) {
226                 printf("chdir(%s) error: %s\n", path, strerror(errno));
227                 EXIT_RET(rc);
228         }
229         return rc;
230 }
231
232 int t_utime(const char *path, const struct utimbuf *buf)
233 {
234         int rc = utime(path, buf);
235         if (rc < 0) {
236                 printf("utime(%s, %p) error: %s\n", path, buf,
237                        strerror(errno));
238                 EXIT_RET(rc);
239         }
240         return rc;
241 }
242
243 int t_opendir(const char *path)
244 {
245         int fd;
246
247         fd = open(path, O_RDONLY);
248         if (fd < 0) {
249                 printf("opendir(%s) error: %s\n", path, strerror(errno));
250                 EXIT_RET(fd);
251         }
252         return fd;
253 }
254
255 void t_close(int fd)
256 {
257         int rc;
258
259         rc = close(fd);
260         if (rc < 0) {
261                 printf("close(%d) error: %s\n", fd, strerror(errno));
262                 EXIT(1);
263         }
264 }
265
266 int t_check_stat(const char *name, struct stat *buf)
267 {
268         struct stat stat;
269         int rc;
270
271         memset(&stat, 0, sizeof(stat));
272
273         rc = lstat(name, &stat);
274         if (rc) {
275                 printf("error %d stat %s\n", rc, name);
276                 EXIT_RET(rc);
277         }
278         if (buf)
279                 memcpy(buf, &stat, sizeof(*buf));
280         if (stat.st_blksize == 0) {
281                 printf("error: blksize is 0\n");
282                 EXIT_RET(-EINVAL);
283         }
284
285         return 0;
286 }
287
288 int t_check_stat_fail(const char *name)
289 {
290         struct stat stat;
291         int rc;
292
293         rc = lstat(name, &stat);
294         if (!rc) {
295                 printf("%s still exists\n", name);
296                 EXIT(-1);
297         }
298
299         return 0;
300 }
301
302 void t_echo_create(const char *path, const char *str)
303 {
304         int fd, rc;
305
306         fd = open(path, O_RDWR|O_CREAT, 0644);
307         if (fd < 0) {
308                 printf("open(%s) error: %s\n", path, strerror(errno));
309                 EXIT(fd);
310         }
311
312         if (write(fd, str, strlen(str)+1) != strlen(str)+1) {
313                 printf("write(%s) error: %s\n", path, strerror(errno));
314                 EXIT(fd);
315         }
316
317         rc = close(fd);
318         if (rc) {
319                 printf("close(%s) error: %s\n", path, strerror(errno));
320                 EXIT(rc);
321         }
322 }
323
324 static void _t_grep(const char *path, char *str, int should_contain)
325 {
326         char buf[1024];
327         int fd;
328         int rc;
329         
330         fd = t_open_readonly(path);
331         if (lseek(fd, 0, SEEK_SET) == -1) {
332                 printf("pread_once: seek to 0 error: %s\n", strerror(errno));
333                 EXIT(fd);
334         }
335
336         rc = read(fd, buf, 1023);
337         if (rc < 0) {
338                 printf("grep: read error: %s\n", strerror(errno));
339                 EXIT(-1);
340         }
341         close(fd);
342         buf[rc] = 0;
343
344         if ((strstr(buf, str) != 0) ^ should_contain) {
345                 printf("grep: can't find string %s\n", str);
346                 EXIT(-1);
347         }
348 }
349
350 void t_grep(const char *path, char *str)
351 {
352         _t_grep(path, str, 1);
353 }
354
355 void t_grep_v(const char *path, char *str)
356 {
357         _t_grep(path, str, 0);
358 }
359
360 void t_ls(int fd, char *buf, int size)
361 {
362         struct dirent64 *ent;
363         int rc, pos;
364         loff_t base = 0;
365
366         printf("dir entries listing...\n");
367         while ((rc = getdirentries64(fd, buf, size, &base)) > 0) {
368                 pos = 0;
369                 while (pos < rc) {
370                         ent = (struct dirent64 *) ((char*) buf + pos);
371                         printf("%s\n", ent->d_name);
372                         pos += ent->d_reclen;
373                 }
374         }
375
376         if (rc < 0) {
377                 printf("getdents error %d\n", rc);
378                 EXIT(-1);
379         }
380 }
381
382 int t_fcntl(int fd, int cmd, ...)
383 {
384         va_list ap;
385         long arg;
386         struct flock *lock;
387         int rc = -1;
388
389         va_start(ap, cmd);
390         switch (cmd) {
391         case F_GETFL:
392                 va_end(ap);
393                 rc = fcntl(fd, cmd);
394                 if (rc == -1) {
395                         printf("fcntl GETFL failed: %s\n",
396                                  strerror(errno));
397                         EXIT(1);
398                 }
399                 break;
400         case F_SETFL:
401                 arg = va_arg(ap, long);
402                 va_end(ap);
403                 rc = fcntl(fd, cmd, arg);
404                 if (rc == -1) {
405                         printf("fcntl SETFL %ld failed: %s\n",
406                                  arg, strerror(errno));
407                         EXIT(1);
408                 }
409                 break;
410         case F_GETLK:
411 #ifdef F_GETLK64
412 #if F_GETLK64 != F_GETLK
413         case F_GETLK64:
414 #endif
415 #endif
416         case F_SETLK:
417 #ifdef F_SETLK64
418 #if F_SETLK64 != F_SETLK
419         case F_SETLK64:
420 #endif
421 #endif
422         case F_SETLKW:
423 #ifdef F_SETLKW64
424 #if F_SETLKW64 != F_SETLKW
425         case F_SETLKW64:
426 #endif
427 #endif
428                 lock = va_arg(ap, struct flock *);
429                 va_end(ap);
430                 rc = fcntl(fd, cmd, lock);
431                 if (rc == -1) {
432                         printf("fcntl cmd %d failed: %s\n",
433                                  cmd, strerror(errno));
434                         EXIT(1);
435                 }
436                 break;
437         case F_DUPFD:
438                 arg = va_arg(ap, long);
439                 va_end(ap);
440                 rc = fcntl(fd, cmd, arg);
441                 if (rc == -1) {
442                         printf("fcntl F_DUPFD %d failed: %s\n",
443                                  (int)arg, strerror(errno));
444                         EXIT(1);
445                 }
446                 break;
447         default:
448                 va_end(ap);
449                 printf("fcntl cmd %d not supported\n", cmd);
450                 EXIT(1);
451         }
452         return rc;
453 }
454
455 char *safe_strncpy(char *dst, char *src, int max_size)
456 {
457        int src_size;
458        src_size=strlen(src);
459        if (src_size >= max_size) {
460          src_size=max_size-1;
461        }
462        memcpy(dst, src, src_size);
463        dst[src_size]=0;
464
465        return(dst);
466 }