Whamcloud - gitweb
b=18468
[fs/lustre-release.git] / lustre / tests / flock.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  * lustre/tests/flock.c
37  *
38  * Lustre Light user test program
39  */
40
41 #define _BSD_SOURCE
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <unistd.h>
46 #include <getopt.h>
47 #include <string.h>
48 #include <sys/types.h>
49 #include <sys/stat.h>
50 #include <fcntl.h>
51 #include <sys/queue.h>
52 #include <signal.h>
53 #include <errno.h>
54 #include <dirent.h>
55 #include <sys/uio.h>
56 #include <sys/time.h>
57 #include <stdarg.h>
58
59 static char lustre_path[] = "/mnt/lustre";
60
61 #define ENTRY(str)                                                      \
62         do {                                                            \
63                 char buf[100];                                          \
64                 int len;                                                \
65                 sprintf(buf, "===== START %s: %s ", __FUNCTION__, (str)); \
66                 len = strlen(buf);                                      \
67                 if (len < 79) {                                         \
68                         memset(buf+len, '=', 100-len);                  \
69                         buf[79] = '\n';                                 \
70                         buf[80] = 0;                                    \
71                 }                                                       \
72                 printf("%s", buf);                                      \
73         } while (0)
74
75 #define LEAVE()                                                         \
76         do {                                                            \
77                 char buf[100];                                          \
78                 int len;                                                \
79                 sprintf(buf, "===== END TEST %s: successfully ",        \
80                         __FUNCTION__);                                  \
81                 len = strlen(buf);                                      \
82                 if (len < 79) {                                         \
83                         memset(buf+len, '=', 100-len);                  \
84                         buf[79] = '\n';                                 \
85                         buf[80] = 0;                                    \
86                 }                                                       \
87                 printf("%s", buf);                                      \
88         } while (0)
89
90 #define EXIT return
91
92 #define MAX_PATH_LENGTH 4096
93
94
95 int t_fcntl(int fd, int cmd, ...)
96 {
97         va_list ap;
98         long arg;
99         struct flock *lock;
100         int rc = -1;
101
102         va_start(ap, cmd);
103         switch (cmd) {
104         case F_GETFL:
105                 va_end(ap);
106                 rc = fcntl(fd, cmd);
107                 if (rc == -1) {
108                         printf("fcntl GETFL failed: %s\n",
109                                  strerror(errno));
110                         EXIT(1);
111                 }
112                 break;
113         case F_SETFL:
114                 arg = va_arg(ap, long);
115                 va_end(ap);
116                 rc = fcntl(fd, cmd, arg);
117                 if (rc == -1) {
118                         printf("fcntl SETFL %ld failed: %s\n",
119                                  arg, strerror(errno));
120                         EXIT(1);
121                 }
122                 break;
123         case F_GETLK:
124         case F_SETLK:
125         case F_SETLKW:
126                 lock = va_arg(ap, struct flock *);
127                 va_end(ap);
128                 rc = fcntl(fd, cmd, lock);
129                 if (rc == -1) {
130                         printf("fcntl cmd %d failed: %s\n",
131                                  cmd, strerror(errno));
132                         EXIT(1);
133                 }
134                 break;
135         case F_DUPFD:
136                 arg = va_arg(ap, long);
137                 va_end(ap);
138                 rc = fcntl(fd, cmd, arg);
139                 if (rc == -1) {
140                         printf("fcntl F_DUPFD %d failed: %s\n",
141                                  (int)arg, strerror(errno));
142                         EXIT(1);
143                 }
144                 break;
145         default:
146                 va_end(ap);
147                 printf("fcntl cmd %d not supported\n", cmd);
148                 EXIT(1);
149         }
150         printf("fcntl %d = %d, ltype = %d\n", cmd, rc, lock->l_type);
151         return rc;
152 }
153
154 int t_unlink(const char *path)
155 {
156         int rc;
157
158         rc = unlink(path);
159         if (rc) {
160                 printf("unlink(%s) error: %s\n", path, strerror(errno));
161                 EXIT(-1);
162         }
163         return rc;
164 }
165
166 void t21()
167 {
168         char file[MAX_PATH_LENGTH] = "";
169         int fd, ret;
170         struct flock lock = {
171                 .l_type = F_RDLCK,
172                 .l_whence = SEEK_SET,
173         };
174
175         ENTRY("basic fcntl support");
176         snprintf(file, MAX_PATH_LENGTH, "%s/test_t21_file", lustre_path);
177
178         fd = open(file, O_RDWR|O_CREAT, (mode_t)0666);
179         if (fd < 0) {
180                 printf("error open file: %m\n", file);
181                 exit(-1);
182         }
183
184         t_fcntl(fd, F_SETFL, O_APPEND);
185         if (!(ret = t_fcntl(fd, F_GETFL)) & O_APPEND) {
186                 printf("error get flag: ret %x\n", ret);
187                 exit(-1);
188         }
189
190         t_fcntl(fd, F_SETLK, &lock);
191         t_fcntl(fd, F_GETLK, &lock);
192         lock.l_type = F_WRLCK;
193         t_fcntl(fd, F_SETLKW, &lock);
194         t_fcntl(fd, F_GETLK, &lock);
195         lock.l_type = F_UNLCK;
196         t_fcntl(fd, F_SETLK, &lock);
197
198         close(fd);
199         t_unlink(file);
200         LEAVE();
201 }
202
203
204 int main(int argc, char * const argv[])
205 {
206         /* Set D_VFSTRACE to see messages from ll_file_flock.
207            The test passes either with -o flock or -o noflock 
208            mount -o flock -t lustre uml1:/mds1/client /mnt/lustre */
209         t21();
210
211         printf("completed successfully\n");
212         return 0;
213 }