Whamcloud - gitweb
Branch HEAD
[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  * Lustre Light user test program
5  *
6  *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
7  *
8  *   This file is part of Lustre, http://www.lustre.org.
9  *
10  *   Lustre is free software; you can redistribute it and/or
11  *   modify it under the terms of version 2 of the GNU General Public
12  *   License as published by the Free Software Foundation.
13  *
14  *   Lustre is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *   GNU General Public License for more details.
18  *
19  *   You should have received a copy of the GNU General Public License
20  *   along with Lustre; if not, write to the Free Software
21  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 #define _BSD_SOURCE
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <getopt.h>
30 #include <string.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34 #include <sys/queue.h>
35 #include <signal.h>
36 #include <errno.h>
37 #include <dirent.h>
38 #include <sys/uio.h>
39 #include <sys/time.h>
40 #include <stdarg.h>
41
42 static char lustre_path[] = "/mnt/lustre";
43
44 #define ENTRY(str)                                                      \
45         do {                                                            \
46                 char buf[100];                                          \
47                 int len;                                                \
48                 sprintf(buf, "===== START %s: %s ", __FUNCTION__, (str)); \
49                 len = strlen(buf);                                      \
50                 if (len < 79) {                                         \
51                         memset(buf+len, '=', 100-len);                  \
52                         buf[79] = '\n';                                 \
53                         buf[80] = 0;                                    \
54                 }                                                       \
55                 printf("%s", buf);                                      \
56         } while (0)
57
58 #define LEAVE()                                                         \
59         do {                                                            \
60                 char buf[100];                                          \
61                 int len;                                                \
62                 sprintf(buf, "===== END TEST %s: successfully ",        \
63                         __FUNCTION__);                                  \
64                 len = strlen(buf);                                      \
65                 if (len < 79) {                                         \
66                         memset(buf+len, '=', 100-len);                  \
67                         buf[79] = '\n';                                 \
68                         buf[80] = 0;                                    \
69                 }                                                       \
70                 printf("%s", buf);                                      \
71         } while (0)
72
73 #define EXIT return
74
75 #define MAX_PATH_LENGTH 4096
76
77
78 int t_fcntl(int fd, int cmd, ...)
79 {
80         va_list ap;
81         long arg;
82         struct flock *lock;
83         int rc = -1;
84
85         va_start(ap, cmd);
86         switch (cmd) {
87         case F_GETFL:
88                 va_end(ap);
89                 rc = fcntl(fd, cmd);
90                 if (rc == -1) {
91                         printf("fcntl GETFL failed: %s\n",
92                                  strerror(errno));
93                         EXIT(1);
94                 }
95                 break;
96         case F_SETFL:
97                 arg = va_arg(ap, long);
98                 va_end(ap);
99                 rc = fcntl(fd, cmd, arg);
100                 if (rc == -1) {
101                         printf("fcntl SETFL %ld failed: %s\n",
102                                  arg, strerror(errno));
103                         EXIT(1);
104                 }
105                 break;
106         case F_GETLK:
107         case F_SETLK:
108         case F_SETLKW:
109                 lock = va_arg(ap, struct flock *);
110                 va_end(ap);
111                 rc = fcntl(fd, cmd, lock);
112                 if (rc == -1) {
113                         printf("fcntl cmd %d failed: %s\n",
114                                  cmd, strerror(errno));
115                         EXIT(1);
116                 }
117                 break;
118         case F_DUPFD:
119                 arg = va_arg(ap, long);
120                 va_end(ap);
121                 rc = fcntl(fd, cmd, arg);
122                 if (rc == -1) {
123                         printf("fcntl F_DUPFD %d failed: %s\n",
124                                  (int)arg, strerror(errno));
125                         EXIT(1);
126                 }
127                 break;
128         default:
129                 va_end(ap);
130                 printf("fcntl cmd %d not supported\n", cmd);
131                 EXIT(1);
132         }
133         printf("fcntl %d = %d, ltype = %d\n", cmd, rc, lock->l_type);
134         return rc;
135 }
136
137 int t_unlink(const char *path)
138 {
139         int rc;
140
141         rc = unlink(path);
142         if (rc) {
143                 printf("unlink(%s) error: %s\n", path, strerror(errno));
144                 EXIT(-1);
145         }
146         return rc;
147 }
148
149 void t21()
150 {
151         char file[MAX_PATH_LENGTH] = "";
152         int fd, ret;
153         struct flock lock = {
154                 .l_type = F_RDLCK,
155                 .l_whence = SEEK_SET,
156         };
157
158         ENTRY("basic fcntl support");
159         snprintf(file, MAX_PATH_LENGTH, "%s/test_t21_file", lustre_path);
160
161         fd = open(file, O_RDWR|O_CREAT, (mode_t)0666);
162         if (fd < 0) {
163                 printf("error open file: %m\n", file);
164                 exit(-1);
165         }
166
167         t_fcntl(fd, F_SETFL, O_APPEND);
168         if (!(ret = t_fcntl(fd, F_GETFL)) & O_APPEND) {
169                 printf("error get flag: ret %x\n", ret);
170                 exit(-1);
171         }
172
173         t_fcntl(fd, F_SETLK, &lock);
174         t_fcntl(fd, F_GETLK, &lock);
175         lock.l_type = F_WRLCK;
176         t_fcntl(fd, F_SETLKW, &lock);
177         t_fcntl(fd, F_GETLK, &lock);
178         lock.l_type = F_UNLCK;
179         t_fcntl(fd, F_SETLK, &lock);
180
181         close(fd);
182         t_unlink(file);
183         LEAVE();
184 }
185
186
187 int main(int argc, char * const argv[])
188 {
189         /* Set D_VFSTRACE to see messages from ll_file_flock.
190            The test passes either with -o flock or -o noflock 
191            mount -o flock -t lustre uml1:/mds1/client /mnt/lustre */
192         t21();
193
194         printf("completed successfully\n");
195         return 0;
196 }