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