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