4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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
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
27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, Whamcloud, Inc.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
48 #define MAX_PATH_LENGTH 4096
52 int t_fcntl(int fd, int cmd, ...)
65 fprintf(stderr, "fcntl GETFL failed: %s\n",
71 arg = va_arg(ap, long);
73 rc = fcntl(fd, cmd, arg);
75 fprintf(stderr, "fcntl SETFL %ld failed: %s\n",
76 arg, strerror(errno));
83 lock = va_arg(ap, struct flock *);
85 rc = fcntl(fd, cmd, lock);
87 fprintf(stderr, "fcntl cmd %d failed: %s\n",
88 cmd, strerror(errno));
93 arg = va_arg(ap, long);
95 rc = fcntl(fd, cmd, arg);
97 fprintf(stderr, "fcntl F_DUPFD %d failed: %s\n",
98 (int)arg, strerror(errno));
104 fprintf(stderr, "fcntl cmd %d not supported\n", cmd);
110 int t_unlink(const char *path)
116 fprintf(stderr, "unlink(%s) error: %s\n", path, strerror(errno));
120 /** =================================================================
127 fprintf(stderr, "usage: ./flocks_test 1 on|off -c|-f|-l /path/to/file\n");
130 int t1(int argc, char *argv[])
133 int mount_with_flock = 0;
141 if (!strncmp(argv[2], "on", 3)) {
142 mount_with_flock = 1;
143 } else if (!strncmp(argv[2], "off", 4)) {
144 mount_with_flock = 0;
150 if ((fd = open(argv[4], O_RDWR)) < 0) {
151 fprintf(stderr, "Couldn't open file: %s\n", argv[3]);
155 if (!strncmp(argv[3], "-c", 3)) {
159 fl.l_whence = SEEK_SET;
163 error = fcntl(fd, F_SETLK, &fl);
164 } else if (!strncmp(argv[3], "-l", 3)) {
165 error = lockf(fd, F_LOCK, 1);
166 } else if (!strncmp(argv[3], "-f", 3)) {
167 error = flock(fd, LOCK_EX);
173 if (mount_with_flock)
174 return((error == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
176 return((error == 0) ? EXIT_FAILURE : EXIT_SUCCESS);
179 /** ===============================================================
182 * 2 threads flock ops interweave
189 void* t2_thread1(void *arg)
191 struct flock *lock = ((th_data *)arg)->lock;
192 int fd = ((th_data *)arg)->fd;
194 printf("thread 1: set write lock (blocking)\n");
195 lock->l_type = F_WRLCK;
196 t_fcntl(fd, F_SETLKW, lock);
197 printf("thread 1: set write lock done\n");
198 t_fcntl(fd, F_GETLK, lock);
199 printf("thread 1: unlock\n");
200 lock->l_type = F_UNLCK;
201 t_fcntl(fd, F_SETLK, lock);
202 printf("thread 1: unlock done\n");
206 void* t2_thread2(void *arg)
208 struct flock *lock = ((th_data *)arg)->lock;
209 int fd = ((th_data *)arg)->fd;
212 printf("thread 2: unlock\n");
213 lock->l_type = F_UNLCK;
214 t_fcntl(fd, F_SETLK, lock);
215 printf("thread 2: unlock done\n");
216 printf("thread 2: set write lock (non-blocking)\n");
217 lock->l_type = F_WRLCK;
218 t_fcntl(fd, F_SETLK, lock);
219 printf("thread 2: set write lock done\n");
220 t_fcntl(fd, F_GETLK, lock);
224 int t2(int argc, char* argv[])
226 struct flock lock = {
228 .l_whence = SEEK_SET,
230 char file[MAX_PATH_LENGTH] = "";
235 snprintf(file, MAX_PATH_LENGTH, "%s/test_t2_file", argv[2]);
237 fd = open(file, O_RDWR|O_CREAT, (mode_t)0666);
239 fprintf(stderr, "error open file: %s\n", file);
243 t_fcntl(fd, F_SETFL, O_APPEND);
244 rc = t_fcntl(fd, F_GETFL);
245 if ((rc & O_APPEND) == 0) {
246 fprintf(stderr, "error get flag: ret %x\n", rc);
252 rc = pthread_create(&th1, NULL, t2_thread1, &ta);
254 fprintf(stderr, "error create thread 1\n");
258 rc = pthread_create(&th2, NULL, t2_thread2, &ta);
260 fprintf(stderr, "error create thread 2\n");
264 (void)pthread_join(th1, NULL);
265 (void)pthread_join(th2, NULL);
272 /** =================================================================
275 * Bug 24040: Two conflicting flocks from same process different fds should fail
276 * two conflicting flocks from different processes but same fs
279 int t3(int argc, char *argv[])
283 int rc = EXIT_SUCCESS;
286 fprintf(stderr, "Usage: ./flocks_test 3 filename\n");
290 if ((fd = open(argv[2], O_RDWR)) < 0) {
291 fprintf(stderr, "Couldn't open file: %s\n", argv[1]);
294 if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
295 perror("first flock failed");
299 if ((fd2 = open(argv[2], O_RDWR)) < 0) {
300 fprintf(stderr, "Couldn't open file: %s\n", argv[1]);
304 if (flock(fd2, LOCK_EX | LOCK_NB) >= 0) {
305 fprintf(stderr, "Second flock succeeded - FAIL\n");
321 if ((fd2 = open(argv[2], O_RDWR)) < 0) {
322 fprintf(stderr, "Couldn't open file: %s\n", argv[1]);
326 if (flock(fd2, LOCK_EX | LOCK_NB) >= 0) {
327 fprintf(stderr, "Second flock succeeded - FAIL\n");
331 if (flock(fd, LOCK_UN) == -1) {
332 fprintf(stderr, "Child unlock on parent fd failed\n");
336 if (flock(fd2, LOCK_EX | LOCK_NB) == -1) {
337 fprintf(stderr, "Relock after parent unlock failed!\n");
346 waitpid(pid, &rc, 0);
353 /** ==============================================================
358 fprintf(stderr, "usage: ./flocks_test test# [corresponding arguments]\n");
361 int main(int argc, char* argv[])
364 int rc = EXIT_SUCCESS;
370 test_no = atoi(argv[1]);
383 fprintf(stderr, "unknow test number %s\n", argv[1]);