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