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