Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / tests / parallel_grouplock.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Copyright (C) 2002 Cluster File Systems, Inc.
5  *   Author: You Feng <youfeng@clusterfs.com>
6  *
7  *   This file is part of Lustre, http://www.lustre.org.
8  *
9  *   Lustre is free software; you can redistribute it and/or
10  *   modify it under the terms of version 2 of the GNU General Public
11  *   License as published by the Free Software Foundation.
12  *
13  *   Lustre is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *   GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with Lustre; if not, write to the Free Software
20  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 #include <mpi.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <sys/ioctl.h>
31 #include <unistd.h>
32 #include <time.h>
33 #include <errno.h>
34 #include <lustre/lustre_user.h>
35 #include "lp_utils.h"
36
37 #define LPGL_FILEN 700000
38 #define LPGL_TEST_ITEMS 7
39
40 #define MAX_GLHOST 4
41
42 /* waiting time in 0.1 s */
43 #define MAX_WAITING_TIME 20
44 int rank = 0;
45 int size = 0;
46
47 char *testdir = NULL;
48
49 /*
50  * process1 attempts CW(gid=1) -- granted immediately
51  * process2 attempts PR -- blocked, goes on waiting list
52  * process3 attempts CW(gid=1) -> should be granted, but may go on
53  *                                the waiting list
54  */
55 void grouplock_test1(char *filename, int fd, char *errmsg)
56 {
57         int rc, count, gid = 1;
58         char buf[LPGL_FILEN];
59         char zeros[LPGL_FILEN];
60         MPI_Request req1, req2;
61         int temp1, temp2;
62
63         if (rank == 0) {
64                 if ((rc = ioctl(fd, LL_IOC_GROUP_LOCK, gid)) == -1) {
65                         sprintf(errmsg, "ioctl GROUP_LOCK of file %s return %d",
66                                 filename, rc);
67                         FAIL(errmsg);
68                 }
69         }
70
71         MPI_Barrier(MPI_COMM_WORLD);
72
73         if (rank == 1) {
74                 memset(zeros, 0x0, sizeof(zeros));
75                 lseek(fd, 0, SEEK_SET);
76
77                 MPI_Send(&gid, 1, MPI_INT, 2, 1, MPI_COMM_WORLD);
78                 count = read(fd, buf, sizeof(buf));
79                 if (count != sizeof(buf)) {
80                         if (count > 0)
81                                 dump_diff(zeros, buf, count, 0);
82                         sprintf(errmsg, "read of file %s return %d",
83                                 filename, count);
84                         FAIL(errmsg);
85                 }
86                 MPI_Send(&gid, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
87         }
88
89         if (rank == 2) {
90                 int temp;
91
92                 /* Wait for reading task to progress, this is probably somewhat
93                    racey, though, may be adding usleep here would make things
94                    better here. */
95                 usleep(100);
96                 MPI_Recv(&temp, 1, MPI_INT, 1, 1, MPI_COMM_WORLD,
97                          MPI_STATUS_IGNORE);
98                 if ((rc = ioctl(fd, LL_IOC_GROUP_LOCK, gid)) == -1) {
99                         sprintf(errmsg, "ioctl GROUP_LOCK of file %s return %d",
100                                 filename, rc);
101                         FAIL(errmsg);
102                 }
103                 MPI_Send(&gid, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
104         }
105
106         if (rank == 0) {
107                 int iter = MAX_WAITING_TIME;
108                 int flag1, flag2;
109
110                 /* reading task will tell us when it completes */
111                 MPI_Irecv(&temp1, 1, MPI_INT, 1, 1, MPI_COMM_WORLD, &req1);
112                 /* 2nd locking task will tell us when it completes */
113                 MPI_Irecv(&temp2, 1, MPI_INT, 2, 1, MPI_COMM_WORLD, &req2);
114
115                 do {
116                         iter--;
117                         if (!iter) {
118                                 FAIL("2nd locking task is not progressing\n");
119                         }
120                         usleep(100);
121                         MPI_Test(&req2, &flag2, MPI_STATUS_IGNORE);
122                         MPI_Test(&req1, &flag1, MPI_STATUS_IGNORE);
123                         if (flag1) {
124                                 FAIL("PR task progressed even though GROUP lock"
125                                      " is held\n");
126                         }
127                 } while (!flag2);
128         }
129
130         /* Now we need to release the lock */
131
132         if (rank == 0 || rank == 2) {
133                 if ((rc = ioctl(fd, LL_IOC_GROUP_UNLOCK, gid)) == -1) {
134                         sprintf(errmsg, "ioctl GROUP_UNLOCK of file %s return %d",
135                                 filename, rc);
136                         FAIL(errmsg);
137                 }
138         }
139
140         if (rank == 0) {
141                 int iter = MAX_WAITING_TIME;
142                 int flag1;
143
144                 do {
145                         iter--;
146                         if (!iter) {
147                                 FAIL("reading task is not progressing even "
148                                      "though GROUP lock was released\n");
149                                 break;
150                         }
151                         usleep(100);
152                         MPI_Test(&req1, &flag1, MPI_STATUS_IGNORE);
153                 } while (!flag1);
154         }
155
156         MPI_Barrier(MPI_COMM_WORLD);
157
158 }
159
160 /*
161  * process1 attempts CW(gid=1) -- granted immediately
162  * process2 attempts CW(gid=2) -- blocked
163  * process3 attempts PR -- blocked
164  * process4 attempts CW(gid=2) -- blocked
165  * process1 releases CW(gid=1) -- this allows process2's CW lock to be granted
166                                   process3 remains blocked
167  */
168 void grouplock_test2(char *filename, int fd, char *errmsg)
169 {
170         int rc, count, gid = 1;
171         char buf[LPGL_FILEN];
172         char zeros[LPGL_FILEN];
173         MPI_Request req1, req2, req3;
174         int temp1, temp2, temp3;
175
176         if (rank == 0) {
177                 if ((rc = ioctl(fd, LL_IOC_GROUP_LOCK, gid)) == -1) {
178                         sprintf(errmsg, "ioctl GROUP_LOCK of file %s return %d",
179                                 filename, rc);
180                         FAIL(errmsg);
181                 }
182         }
183
184         MPI_Barrier(MPI_COMM_WORLD);
185
186         if (rank == 1 || rank == 3) {
187                 gid = 2;
188                 if (rank == 3) {
189                         MPI_Recv(&temp1, 1, MPI_INT, 2, 1, MPI_COMM_WORLD,
190                                  MPI_STATUS_IGNORE);
191                         usleep(100);
192                 }
193                 if ((rc = ioctl(fd, LL_IOC_GROUP_LOCK, gid)) == -1) {
194                         sprintf(errmsg, "ioctl GROUP_LOCK of file %s return %d",
195                                 filename, rc);
196                         FAIL(errmsg);
197                 }
198                 MPI_Send(&gid, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
199         }
200
201         if (rank == 2) {
202                 memset(zeros, 0x0, sizeof(zeros));
203                 lseek(fd, 0, SEEK_SET);
204
205                 MPI_Send(&gid, 1, MPI_INT, 3, 1, MPI_COMM_WORLD);
206                 count = read(fd, buf, sizeof(buf));
207                 if (count != sizeof(buf)) {
208                         if (count > 0)
209                                 dump_diff(zeros, buf, count, 0);
210                         sprintf(errmsg, "read of file %s return %d",
211                                 filename, count);
212                         FAIL(errmsg);
213                 }
214                 MPI_Send(&gid, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
215         }
216
217         if (rank == 0) {
218                 int iter = MAX_WAITING_TIME;
219                 int flag1, flag2, flag3;
220
221                 /* 2nd locking task will tell us when it completes */
222                 MPI_Irecv(&temp1, 1, MPI_INT, 1, 1, MPI_COMM_WORLD, &req1);
223                 /* 3nd locking task will tell us when it completes */
224                 MPI_Irecv(&temp2, 1, MPI_INT, 3, 1, MPI_COMM_WORLD, &req2);
225                 /* reading task will tell us when it completes */
226                 MPI_Irecv(&temp3, 1, MPI_INT, 2, 1, MPI_COMM_WORLD, &req3);
227
228                 do {
229                         iter--;
230                         usleep(100);
231                         MPI_Test(&req2, &flag2, MPI_STATUS_IGNORE);
232                         MPI_Test(&req1, &flag1, MPI_STATUS_IGNORE);
233                         MPI_Test(&req3, &flag3, MPI_STATUS_IGNORE);
234                         if (flag3) {
235                                 FAIL("PR task progressed even though GROUP lock"
236                                      " is held\n");
237                         }
238                         if (flag1 || flag2) {
239                                 FAIL("GROUP (gid=2) task progressed even though"
240                                      " GROUP (gid=1) lock is held\n");
241                         }
242
243                 } while (iter);
244
245                 /* Now let's release first lock */
246                 if ((rc = ioctl(fd, LL_IOC_GROUP_UNLOCK, gid)) == -1) {
247                         sprintf(errmsg, "ioctl GROUP_UNLOCK of file %s return %d",
248                                 filename, rc);
249                         FAIL(errmsg);
250                 }
251                 iter = MAX_WAITING_TIME;
252                 do {
253                         iter--;
254                         if (!iter) {
255                                 FAIL("GROUP(gid=2) tasks are not progressing\n");
256                         }
257                         usleep(100);
258                         MPI_Test(&req2, &flag2, MPI_STATUS_IGNORE);
259                         MPI_Test(&req1, &flag1, MPI_STATUS_IGNORE);
260                         MPI_Test(&req3, &flag3, MPI_STATUS_IGNORE);
261                         if (flag3) {
262                                 fprintf(stderr, "task1 %d, task3 %d\n", flag1,
263                                         flag2);
264                                 FAIL("PR task progressed even though GROUP lock"
265                                      " was on the queue task\n");
266                         }
267                 } while (!(flag1 && flag2));
268                 MPI_Send(&gid, 1, MPI_INT, 1, 1, MPI_COMM_WORLD);
269                 MPI_Send(&gid, 1, MPI_INT, 3, 1, MPI_COMM_WORLD);
270         }
271
272         if (rank == 1 || rank == 3) {
273                 /* Do not release the locks until task 0 is ready to watch
274                    for reading task only */
275                 MPI_Recv(&temp1, 1, MPI_INT, 0, 1, MPI_COMM_WORLD,
276                          MPI_STATUS_IGNORE);
277                 if ((rc = ioctl(fd, LL_IOC_GROUP_UNLOCK, gid)) == -1) {
278                         sprintf(errmsg, "ioctl GROUP_UNLOCK of file %s return %d",
279                                 filename, rc);
280                         FAIL(errmsg);
281                 }
282         }
283
284         if (rank == 0) {
285                 int iter = MAX_WAITING_TIME;
286                 int flag3;
287
288                 do {
289                         iter--;
290                         if (!iter) {
291                                 FAIL("reading task is not progressing even "
292                                      "though GROUP locks are released\n");
293                                 break;
294                         }
295                         usleep(100);
296                         MPI_Test(&req3, &flag3, MPI_STATUS_IGNORE);
297                 } while (!flag3);
298         }
299
300         MPI_Barrier(MPI_COMM_WORLD);
301
302 }
303
304 /*
305  * process1 attempts CW(gid=1) -- granted
306  * process2 attempts PR -- blocked
307  * process3 attempts CW(gid=1) -> should be granted
308  * process3 releases CW(gid=1)
309  *   process2 should remain blocked
310  * process1 releases CW(gid=1)
311  *   process2's PR should be granted
312  *
313  * This is a lot like test1.
314  */
315 void grouplock_test3(char *filename, int fd, char *errmsg)
316 {
317         int rc, count, gid = 1;
318         char buf[LPGL_FILEN];
319         char zeros[LPGL_FILEN];
320         MPI_Request req1, req2;
321         int temp1, temp2;
322
323         if (rank == 0) {
324                 if ((rc = ioctl(fd, LL_IOC_GROUP_LOCK, gid)) == -1) {
325                         sprintf(errmsg, "ioctl GROUP_LOCK of file %s return %d",
326                                 filename, rc);
327                         FAIL(errmsg);
328                 }
329         }
330
331         MPI_Barrier(MPI_COMM_WORLD);
332
333         if (rank == 1) {
334                 memset(zeros, 0x0, sizeof(zeros));
335                 lseek(fd, 0, SEEK_SET);
336
337                 MPI_Send(&gid, 1, MPI_INT, 2, 1, MPI_COMM_WORLD);
338                 count = read(fd, buf, sizeof(buf));
339                 if (count != sizeof(buf)) {
340                         if (count > 0)
341                                 dump_diff(zeros, buf, count, 0);
342                         sprintf(errmsg, "read of file %s return %d",
343                                 filename, count);
344                         FAIL(errmsg);
345                 }
346                 MPI_Send(&gid, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
347         }
348
349         if (rank == 2) {
350                 int temp;
351
352                 /* Wait for reading task to progress, this is probably somewhat
353                    racey, though, may be adding usleep here would make things
354                    better here. */
355                 usleep(100);
356                 MPI_Recv(&temp, 1, MPI_INT, 1, 1, MPI_COMM_WORLD,
357                          MPI_STATUS_IGNORE);
358                 if ((rc = ioctl(fd, LL_IOC_GROUP_LOCK, gid)) == -1) {
359                         sprintf(errmsg, "ioctl GROUP_LOCK of file %s return %d",
360                                 filename, rc);
361                         FAIL(errmsg);
362                 }
363                 MPI_Send(&gid, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
364         }
365
366         if (rank == 0) {
367                 int iter = MAX_WAITING_TIME;
368                 int flag1, flag2;
369
370                 /* reading task will tell us when it completes */
371                 MPI_Irecv(&temp1, 1, MPI_INT, 1, 1, MPI_COMM_WORLD, &req1);
372                 /* 2nd locking task will tell us when it completes */
373                 MPI_Irecv(&temp2, 1, MPI_INT, 2, 1, MPI_COMM_WORLD, &req2);
374
375                 do {
376                         iter--;
377                         if (!iter) {
378                                 FAIL("2nd locking task is not progressing\n");
379                         }
380                         usleep(100);
381                         MPI_Test(&req2, &flag2, MPI_STATUS_IGNORE);
382                         MPI_Test(&req1, &flag1, MPI_STATUS_IGNORE);
383                         if (flag1) {
384                                 FAIL("PR task progressed even though GROUP lock"
385                                      " is held\n");
386                         }
387                 } while (!flag2);
388         }
389
390         /* Now we need to release the lock */
391
392         if (rank == 2) {
393                 if ((rc = ioctl(fd, LL_IOC_GROUP_UNLOCK, gid)) == -1) {
394                         sprintf(errmsg, "ioctl GROUP_UNLOCK of file %s return %d",
395                                 filename, rc);
396                         FAIL(errmsg);
397                 }
398         }
399
400         if (rank == 0) {
401                 int iter = MAX_WAITING_TIME;
402                 int flag1;
403
404                 do {
405                         iter--;
406                         usleep(100);
407                         MPI_Test(&req1, &flag1, MPI_STATUS_IGNORE);
408                 } while (!flag1 && iter);
409                 if (iter) {
410                         FAIL("reading task is progressing even "
411                              "though GROUP lock was not fully released\n");
412                 }
413
414                 iter = MAX_WAITING_TIME;
415
416                 if ((rc = ioctl(fd, LL_IOC_GROUP_UNLOCK, gid)) == -1) {
417                         sprintf(errmsg, "ioctl GROUP_UNLOCK of file %s return %d",
418                                 filename, rc);
419                         FAIL(errmsg);
420                 }
421
422                 do {
423                         iter--;
424                         if (!iter) {
425                                 FAIL("reading task is not progressing even "
426                                      "though GROUP lock was released\n");
427                                 break;
428                         }
429                         usleep(100);
430                         MPI_Test(&req1, &flag1, MPI_STATUS_IGNORE);
431                 } while (!flag1);
432         }
433
434         MPI_Barrier(MPI_COMM_WORLD);
435
436 }
437
438 /*
439  * process1 attempts CW(gid=1) -- granted
440  * process2 attempts PR on non-blocking fd -> should return -EWOULDBLOCK
441  * process3 attempts CW(gid=2) on non-blocking fd -> should return -EWOULDBLOCK
442  */
443 void grouplock_test4(char *filename, int fd, char *errmsg)
444 {
445         int rc, count, gid = 1;
446         char buf[LPGL_FILEN];
447         char zeros[LPGL_FILEN];
448
449         if (rank == 0) {
450                 if ((rc = ioctl(fd, LL_IOC_GROUP_LOCK, gid)) == -1) {
451                         sprintf(errmsg, "ioctl GROUP_LOCK of file %s return %d",
452                                 filename, rc);
453                         FAIL(errmsg);
454                 }
455         }
456
457         MPI_Barrier(MPI_COMM_WORLD);
458
459         if (rank == 1) {
460                 memset(zeros, 0x0, sizeof(zeros));
461                 lseek(fd, 0, SEEK_SET);
462
463                 count = read(fd, buf, sizeof(buf));
464                 if (count != sizeof(buf)) {
465                         if (count == -1 && errno == EWOULDBLOCK) {
466                                 MPI_Send(&gid, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
467                                 return;
468                         }
469
470                         if (count > 0)
471                                 dump_diff(zeros, buf, count, 0);
472                         sprintf(errmsg, "read of file %s return %d",
473                                 filename, count);
474                         FAIL(errmsg);
475                 } else {
476                         FAIL("PR lock succeed while incompatible "
477                              "GROUP LOCK (gid=1) is still held\n");
478                 }
479         }
480
481         if (rank == 2) {
482                 gid = 2;
483                 if ((rc = ioctl(fd, LL_IOC_GROUP_LOCK, gid)) == -1) {
484                         if (errno == EWOULDBLOCK) {
485                                 MPI_Send(&gid, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
486                                 return;
487                         }
488
489                         sprintf(errmsg, "ioctl GROUP_LOCK of file %s return %d",
490                                 filename, rc);
491                         FAIL(errmsg);
492                 } else {
493                         FAIL("GROUP_LOCK (gid=2) succeed while incompatible "
494                              "GROUP LOCK (gid=1) is still held\n");
495                 }
496         }
497
498
499         if ( rank == 0) {
500                 int iter = MAX_WAITING_TIME;
501                 int flag1, flag2;
502                 MPI_Request req1, req2;
503                 int temp1, temp2;
504
505                 /* reading task will tell us when it completes */
506                 MPI_Irecv(&temp1, 1, MPI_INT, 1, 1, MPI_COMM_WORLD, &req1);
507                 /* 2nd locking task will tell us when it completes */
508                 MPI_Irecv(&temp2, 1, MPI_INT, 2, 1, MPI_COMM_WORLD, &req2);
509
510                 do {
511                         iter--;
512                         if (!iter) {
513                                 FAIL("non-blocking tasks are not progressing\n");
514                         }
515                         usleep(100);
516                         MPI_Test(&req2, &flag2, MPI_STATUS_IGNORE);
517                         MPI_Test(&req1, &flag1, MPI_STATUS_IGNORE);
518                 } while (!(flag2 && flag1));
519
520                 if ((rc = ioctl(fd, LL_IOC_GROUP_UNLOCK, gid)) == -1) {
521                         sprintf(errmsg, "ioctl GROUP_UNLOCK of file %s", filename);
522                         FAIL(errmsg);
523                 }
524         }
525 }
526
527 /*
528  * process1 attempts CW(gid=1) -- granted
529  * process2 attempts CW(gid=2) -- blocked
530  * process3 attempts CW(gid=2) -- blocked
531  * process1 releases CW(gid=1)
532  *   process2's CW(gid=2) should be granted
533  *   process3's CW(gid=2) should be granted
534  *
535  * This is pretty much like test 3
536  */
537 void grouplock_test5(char *filename, int fd, char *errmsg)
538 {
539         int rc, gid = 1;
540         MPI_Request req1, req2;
541         int temp1, temp2;
542
543         if (rank == 0) {
544                 if ((rc = ioctl(fd, LL_IOC_GROUP_LOCK, gid)) == -1) {
545                         sprintf(errmsg, "ioctl GROUP_LOCK of file %s return %d",
546                                 filename, rc);
547                         FAIL(errmsg);
548                 }
549         }
550
551         MPI_Barrier(MPI_COMM_WORLD);
552
553         if (rank == 2 || rank == 1) {
554                 gid = 2;
555                 if ((rc = ioctl(fd, LL_IOC_GROUP_LOCK, gid)) == -1) {
556                         sprintf(errmsg, "ioctl GROUP_LOCK of file %s return %d",
557                                 filename, rc);
558                         FAIL(errmsg);
559                 }
560                 MPI_Send(&gid, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
561         }
562
563         if (rank == 0) {
564                 int iter = MAX_WAITING_TIME;
565                 int flag1, flag2;
566
567                 /* 3rd locking task will tell us when it completes */
568                 MPI_Irecv(&temp1, 1, MPI_INT, 1, 1, MPI_COMM_WORLD, &req1);
569                 /* 2nd locking task will tell us when it completes */
570                 MPI_Irecv(&temp2, 1, MPI_INT, 2, 1, MPI_COMM_WORLD, &req2);
571
572                 do {
573                         iter--;
574                         usleep(100);
575                         MPI_Test(&req2, &flag2, MPI_STATUS_IGNORE);
576                         MPI_Test(&req1, &flag1, MPI_STATUS_IGNORE);
577                 } while (!flag2 && !flag1 && iter);
578                 if (iter) {
579                         FAIL("incomptible locking tasks are progressing\n");
580                 }
581         }
582
583         /* Now we need to release the lock */
584
585         if (rank == 0) {
586                 int iter = MAX_WAITING_TIME;
587                 int flag1, flag2;
588                 if ((rc = ioctl(fd, LL_IOC_GROUP_UNLOCK, gid)) == -1) {
589                         sprintf(errmsg, "ioctl GROUP_UNLOCK of file %s return %d",
590                                 filename, rc);
591                         FAIL(errmsg);
592                 }
593
594                 do {
595                         iter--;
596                         if (!iter) {
597                                 FAIL("locking tasks are not progressing even "
598                                      "though incompatible lock released\n");
599                         }
600                         usleep(100);
601                         MPI_Test(&req1, &flag1, MPI_STATUS_IGNORE);
602                         MPI_Test(&req2, &flag2, MPI_STATUS_IGNORE);
603                 } while (!(flag1 && flag2));
604
605         }
606
607         if ( rank == 1 || rank == 2) {
608                 if ((rc = ioctl(fd, LL_IOC_GROUP_UNLOCK, gid)) == -1) {
609                         sprintf(errmsg, "ioctl GROUP_UNLOCK of file %s return %d",
610                                 filename, rc);
611                         FAIL(errmsg);
612                 }
613         }
614
615         MPI_Barrier(MPI_COMM_WORLD);
616
617
618 }
619
620 /*
621  * process1 attempts CW(gid=1) -- granted
622  * process2 attempts PW -- blocked
623  * process2 attempts CW(gid=2) -- blocked
624  * process3 attempts CW(gid=2) -- blocked
625  * process1 releases CW(gid=1)
626  *   process2's CW(gid=2) should be granted
627  *   process3's CW(gid=2) should be granted
628  *
629  * after process1 release CW(gid=1), there are two pathes:
630  *   path 1. process2 get PW
631  *   path 2. process3 get CW(gid=2)
632  *
633  * green: Also about test6 - by definition if P* and CW lock are waiting,
634  *        CW lock have bigger priority and should be granted first when it becomes
635  *        possible. So after process1 releases its CW lock, process3 should always
636  *        get CW lock, and when it will release it, process 2 will proceed with read
637  *        and then with getting CW lock
638  *
639  * XXX This test does not make any sence at all the way it is described right
640  * now, hence disabled.
641  */
642 void grouplock_test6(char *filename, int fd, char *errmsg)
643 {
644 }
645
646 /* Just test some error paths with invalid requests */
647 void grouplock_errorstest(char *filename, int fd, char *errmsg)
648 {
649         int gid = 1;
650         int rc;
651
652         /* To not do lots of separate tests with lots of fd opening/closing,
653            different parts of this test are performed in different processes */
654
655         if (rank == 0 || rank == 1 ) {
656                 if ((rc = ioctl(fd, LL_IOC_GROUP_LOCK, gid)) == -1) {
657                         sprintf(errmsg, "ioctl GROUP_LOCK of file %s return %d",
658                                 filename, rc);
659                         FAIL(errmsg);
660                 }
661         }
662
663         /* second group lock on same fd, same gid */
664         if (rank == 0) {
665                 if ((rc = ioctl(fd, LL_IOC_GROUP_LOCK, gid)) == -1) {
666                         if (errno != EINVAL) {
667                                 sprintf(errmsg, "Double GROUP lock failed with errno %d instead of EINVAL\n", errno);
668                                 FAIL(errmsg);
669                         }
670                 } else {
671                         FAIL("Taking second GROUP lock on same fd succeed\n");
672                 }
673         }
674
675         /* second group lock on same fd, different gid */
676         if (rank == 1) {
677                 if ((rc = ioctl(fd, LL_IOC_GROUP_LOCK, gid + 1)) == -1) {
678                         if (errno != EINVAL) {
679                                 sprintf(errmsg, "Double GROUP lock different gid failed with errno %d instead of EINVAL\n", errno);
680                                 FAIL(errmsg);
681                         }
682                 } else {
683                         FAIL("Taking second GROUP lock on same fd, different gid, succeed\n");
684                 }
685         }
686
687         /* GROUP unlock with wrong gid */
688         if (rank == 0 || rank == 1) {
689                 if ((rc = ioctl(fd, LL_IOC_GROUP_UNLOCK, gid + 1)) == -1) {
690                         if (errno != EINVAL) {
691                                 sprintf(errmsg, "GROUP unlock with wrong gid failed with errno %d instead of EINVAL\n",
692                                         errno);
693                                 FAIL(errmsg);
694                         }
695                 } else {
696                         FAIL("GROUP unlock with wrong gid succeed\n");
697                 }
698         }
699
700         if (rank == 0 || rank == 1) {
701                 if ((rc = ioctl(fd, LL_IOC_GROUP_UNLOCK, gid)) == -1) {
702                         sprintf(errmsg, "ioctl GROUP_UNLOCK of file %s return %d",
703                                 filename, rc);
704                         FAIL(errmsg);
705                 }
706         }
707
708         /* unlock of never locked fd */
709         if (rank == 2) {
710                 if ((rc = ioctl(fd, LL_IOC_GROUP_UNLOCK, gid)) == -1) {
711                         if (errno != EINVAL) {
712                                 sprintf(errmsg, "GROUP unlock on never locked fd failed with errno %d instead of EINVAL\n",
713                                         errno);
714                                 FAIL(errmsg);
715                         }
716                 } else {
717                         FAIL("GROUP unlock on never locked fd succeed\n");
718                 }
719         }
720 }
721
722 void grouplock_file(char *name, int items)
723 {
724         int fd;
725         char filename[MAX_FILENAME_LEN];
726         char errmsg[MAX_FILENAME_LEN+20];
727
728         sprintf(filename, "%s/%s", testdir, name);
729
730         if (items == 4) {
731                 if ((fd = open(filename, O_RDWR | O_NONBLOCK)) == -1) {
732                         sprintf(errmsg, "open of file %s", filename);
733                         FAIL(errmsg);
734                 }
735         } else if ((fd = open(filename, O_RDWR)) == -1) {
736                 sprintf(errmsg, "open of file %s", filename);
737                 FAIL(errmsg);
738         }
739
740         MPI_Barrier(MPI_COMM_WORLD);
741
742         switch (items) {
743         case 1:
744                 grouplock_test1(filename, fd, errmsg);
745                 break;
746         case 2:
747                 grouplock_test2(filename, fd, errmsg);
748                 break;
749         case 3:
750                 grouplock_test3(filename, fd, errmsg);
751                 break;
752         case 4:
753                 grouplock_test4(filename, fd, errmsg);
754                 break;
755         case 5:
756                 grouplock_test5(filename, fd, errmsg);
757                 break;
758         case 6:
759                 grouplock_test6(filename, fd, errmsg);
760                 break;
761         case 7:
762                 grouplock_errorstest(filename, fd, errmsg);
763                 break;
764         default:
765                 sprintf(errmsg, "wrong test case number %d (should be <= %d)",
766                         items, LPGL_TEST_ITEMS);
767                 FAIL(errmsg);
768         }
769
770         MPI_Barrier(MPI_COMM_WORLD);
771
772         if (close(fd) == -1) {
773                 sprintf(errmsg, "close of file %s", filename);
774                 FAIL(errmsg);
775         }
776
777 }
778
779 void parallel_grouplock(void)
780 {
781         int i;
782
783         for (i = 1;i <= LPGL_TEST_ITEMS;++i) {
784                 begin("setup");
785                 create_file("parallel_grouplock", LPGL_FILEN, 0);
786                 end("setup");
787
788                 begin("test");
789                 grouplock_file("parallel_grouplock", i);
790                 end("test");
791
792                 begin("cleanup");
793                 remove_file("parallel_grouplock");
794                 end("cleanup");
795         }
796 }
797
798 void usage(char *proc)
799 {
800         int i;
801
802         if (rank == 0) {
803                 printf("Usage: %s [-h] -d <testdir>\n", proc);
804                 printf("           [-n \"13\"] [-v] [-V #] [-g]\n");
805                 printf("\t-h: prints this help message\n");
806                 printf("\t-d: the directory in which the tests will run\n");
807                 printf("\t-n: repeat test # times\n");
808                 printf("\t-v: increase the verbositly level by 1\n");
809                 printf("\t-V: select a specific verbosity level\n");
810                 printf("\t-g: debug mode\n");
811         }
812
813         MPI_Initialized(&i);
814         if (i) MPI_Finalize();
815         exit(0);
816 }
817
818 int main(int argc, char *argv[])
819 {
820         char c;
821         int i, iterations = 1;
822
823         /* Check for -h parameter before MPI_Init so the binary can be
824            called directly, without, for instance, mpirun */
825         for (i = 1; i < argc; ++i) {
826                 if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help"))
827                         usage(argv[0]);
828         }
829
830         MPI_Init(&argc, &argv);
831         MPI_Comm_rank(MPI_COMM_WORLD, &rank);
832         MPI_Comm_size(MPI_COMM_WORLD, &size);
833
834 //        MPI_Comm_set_attr(MPI_COMM_WORLD, MPI_WTIME_IS_GLOBAL, &tr);
835
836         /* Parse command line options */
837         while (1) {
838                 c = getopt(argc, argv, "d:ghn:vV:");
839                 if (c == -1)
840                         break;
841
842                 switch (c) {
843                 case 'd':
844                         testdir = optarg;
845                         break;
846                 case 'g':
847                         debug = 1;
848                         break;
849                 case 'h':
850                         usage(argv[0]);
851                         break;
852                 case 'n':
853                         iterations = atoi(optarg);
854                         break;
855                 case 'v':
856                         verbose += 1;
857                         break;
858                 case 'V':
859                         verbose = atoi(optarg);
860                         break;
861                 }
862         }
863
864         if (rank == 0)
865                 printf("%s is running with %d process(es) %s\n",
866                        argv[0], size, debug ? "in DEBUG mode" : "\b\b");
867
868         if (size < MAX_GLHOST) {
869                 fprintf(stderr, "Error: "
870                         "should be at least four processes to run the test!\n");
871                 MPI_Abort(MPI_COMM_WORLD, 2);
872         }
873
874         if (testdir == NULL && rank == 0) {
875                 fprintf(stderr, "Please specify a test directory! "
876                         "(\"%s -h\" for help)\n", argv[0]);
877                 MPI_Abort(MPI_COMM_WORLD, 2);
878         }
879
880         lp_gethostname();
881
882         for (i = 0; i < iterations; ++i) {
883                 if (rank == 0)
884                         printf("%s: Running test #%s(iter %d)\n",
885                                timestamp(), argv[0], i);
886
887                 parallel_grouplock();
888                 MPI_Barrier(MPI_COMM_WORLD);
889         }
890
891         if (rank == 0) {
892                 printf("%s: All tests passed!\n", timestamp());
893         }
894         MPI_Finalize();
895         return 0;
896 }