src/locktest: Remove unnecessary sleep
[xfstests-dev.git] / src / locktest.c
index a108b6f4203417fc500514d715d1ddef15d1f281..29e914febdf9b863c1582cebcb758ead83f60ad3 100644 (file)
@@ -1,19 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2000-2003 Silicon Graphics, Inc.
  * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 /*
@@ -73,8 +61,7 @@ extern int h_errno;
        
 #define HANDLE              int
 #define INVALID_HANDLE      -1
-#define OPEN(N,F)           (open(N, F|O_CREAT|O_RDWR|O_BINARY| \
-                            (D_flag ? O_DIRECT : 0), 0644))
+#define OPEN(N,F)           (open(N, F|O_CREAT|O_BINARY, 0644))
 #define SEEK(H, O)          (lseek(H, O, SEEK_SET))
 #define READ(H, B, L)       (read(H, B, L))
 #define WRITE(H, B, L)      (write(H, B, L))
@@ -82,7 +69,6 @@ extern int h_errno;
 
 #define RAND()              (rand())
 #define SRAND(s)            (srand(s))
-#define SLEEP(s)            (sleep(s))
 
 #define MIN(A,B)            (((A)<(B))?(A):(B))
 #define MAX(A,B)            (((A)>(B))?(A):(B))
@@ -94,24 +80,21 @@ static char *prog;
 static char    *filename = 0;
 static int     debug = 0;
 static int     server = 1;
-static int     maxio = 8192;
-static int     port = 7890;
-static int     reopen=0;
-static int     closed=0;
+static int     port = 0;
 static int     testnumber = -1;
 static int     saved_errno = 0;
 
 static SOCKET  s_fd = -1;              /* listen socket    */
 static SOCKET  c_fd = -1;              /* IPC socket       */
 static HANDLE  f_fd = INVALID_HANDLE;  /* shared file      */
-static char    *buf;                   /* I/O buffer       */
-static int     D_flag = 0;
 
 #define        WRLOCK  0
 #define        RDLOCK  1
 #define                UNLOCK  2
 #define                F_CLOSE 3
 #define                F_OPEN  4
+#define                WRTEST  5
+#define                RDTEST  6
 
 #define                PASS    1
 #define                FAIL    0
@@ -180,15 +163,16 @@ char *descriptions[] = {
     /* 26 */"Acquire read and write locks with overlapping ranges",
     /* 27 */"Acquire whole file write lock and then close without unlocking (and attempt a lock)",
     /* 28 */"Acquire two read locks, close and reopen the file, and test if the inital lock is still there",
+    /* 29 */"Verify that F_GETLK for F_WRLCK doesn't require that file be opened for write",
     #if defined(macosx)
-    /* 29 */"Close the opened file and open the file with SHLOCK, other client will try to open with SHLOCK too",
-    /* 30 */"Close the opened file and open the file with SHLOCK, other client will try to open with EXLOCK",
-    /* 31 */"Close the opened file and open the file with EXLOCK, other client will try to open with EXLOCK too"
+    /* 30 */"Close the opened file and open the file with SHLOCK, other client will try to open with SHLOCK too",
+    /* 31 */"Close the opened file and open the file with SHLOCK, other client will try to open with EXLOCK",
+    /* 32 */"Close the opened file and open the file with EXLOCK, other client will try to open with EXLOCK too"
     #endif
 };
 
 static int64_t tests[][6] =
-       /*      test #  Action  offset          length          expected        server/client */
+       /*      test #  Action  [offset|flags]  length          expected        server/client */
        {       
        /* Various simple tests exercising the list */
 
@@ -512,35 +496,41 @@ static int64_t tests[][6] =
                {27,    WRLOCK, 1,              5,              FAIL,           CLIENT, },
                {27,    F_CLOSE,0,              0,              PASS,           SERVER, },
                {27,    WRLOCK, 1,              5,              PASS,           CLIENT, },
-               {27,    F_OPEN, 0,              0,              PASS,           SERVER, },
+               {27,    F_OPEN, O_RDWR,         0,              PASS,           SERVER, },
                {27,    UNLOCK, 1,              5,              PASS,           CLIENT, },
        /* Acquire two read locks, close one file and then reopen to check that first lock still exists */
                {28,    RDLOCK, 1,              5,              PASS,           SERVER, },
                {28,    RDLOCK, 1,              5,              PASS,           CLIENT, },
                {28,    F_CLOSE,0,              0,              PASS,           SERVER, },
-               {28,    F_OPEN, 0,              0,              PASS,           SERVER, },
+               {28,    F_OPEN, O_RDWR,         0,              PASS,           SERVER, },
                {28,    WRLOCK, 0,              0,              FAIL,           SERVER, },
                {28,    UNLOCK, 1,              5,              PASS,           SERVER, },
+       /* Verify that F_GETLK for F_WRLCK doesn't require that file be opened for write */
+               {29,    F_CLOSE, 0,             0,              PASS,           SERVER, },
+               {29,    F_OPEN, O_RDONLY,       0,              PASS,           SERVER, },
+               {29,    WRTEST, 0,              0,              PASS,           SERVER, },
+               {29,    F_CLOSE,0,              0,              PASS,           SERVER, },
+               {29,    F_OPEN, O_RDWR,         0,              PASS,           SERVER, },
 #ifdef macosx
        /* Close the opened file and open the file with SHLOCK, other client will try to open with SHLOCK too */
-               {29,    F_CLOSE,0,              0,              PASS,           SERVER, },
-               {29,    F_OPEN, O_SHLOCK|O_NONBLOCK,    0,      PASS,           SERVER, },
-               {29,    F_CLOSE,0,              0,              PASS,           CLIENT, },
-               {29,    F_OPEN, O_SHLOCK|O_NONBLOCK,    0,      PASS,           CLIENT, },
-       /* Close the opened file and open the file with SHLOCK, other client will try to open with EXLOCK */
                {30,    F_CLOSE,0,              0,              PASS,           SERVER, },
+               {30,    F_OPEN, O_RDWR|O_SHLOCK|O_NONBLOCK,     0,      PASS,           SERVER, },
                {30,    F_CLOSE,0,              0,              PASS,           CLIENT, },
-               {30,    F_OPEN, O_SHLOCK|O_NONBLOCK,    0,      PASS,           SERVER, },
-               {30,    F_OPEN, O_EXLOCK|O_NONBLOCK,    0,      FAIL,           CLIENT, },
-       /* Close the opened file and open the file with EXLOCK, other client will try to open with EXLOCK too */
-               {31,    F_CLOSE,0,              0,              PASS,           SERVER, },
-               {31,    F_CLOSE,0,              0,              FAIL,           CLIENT, },
-               {31,    F_OPEN, O_EXLOCK|O_NONBLOCK,    0,      PASS,           SERVER, },
-               {31,    F_OPEN, O_EXLOCK|O_NONBLOCK,    0,      FAIL,           CLIENT, },
+               {30,    F_OPEN, O_RDWR|O_SHLOCK|O_NONBLOCK,     0,      PASS,           CLIENT, },
+       /* Close the opened file and open the file with SHLOCK, other client will try to open with EXLOCK */
                {31,    F_CLOSE,0,              0,              PASS,           SERVER, },
-               {31,    F_CLOSE,0,              0,              FAIL,           CLIENT, },
-               {31,    F_OPEN, 0,              0,              PASS,           SERVER, },
-               {31,    F_OPEN, 0,              0,              PASS,           CLIENT, },
+               {31,    F_CLOSE,0,              0,              PASS,           CLIENT, },
+               {31,    F_OPEN, O_RDWR|O_SHLOCK|O_NONBLOCK,     0,      PASS,           SERVER, },
+               {31,    F_OPEN, O_RDWR|O_EXLOCK|O_NONBLOCK,     0,      FAIL,           CLIENT, },
+       /* Close the opened file and open the file with EXLOCK, other client will try to open with EXLOCK too */
+               {32,    F_CLOSE,0,              0,              PASS,           SERVER, },
+               {32,    F_CLOSE,0,              0,              FAIL,           CLIENT, },
+               {32,    F_OPEN, O_RDWR|O_EXLOCK|O_NONBLOCK,     0,      PASS,           SERVER, },
+               {32,    F_OPEN, O_RDWR|O_EXLOCK|O_NONBLOCK,     0,      FAIL,           CLIENT, },
+               {32,    F_CLOSE,0,              0,              PASS,           SERVER, },
+               {32,    F_CLOSE,0,              0,              FAIL,           CLIENT, },
+               {32,    F_OPEN, O_RDWR,         0,              PASS,           SERVER, },
+               {32,    F_OPEN, O_RDWR,         0,              PASS,           CLIENT, },
 #endif /* macosx */
        /* indicate end of array */
                {0,0,0,0,0,SERVER},
@@ -584,12 +574,7 @@ initialize(HANDLE fd)
     int        offset = 0;
     int        togo = FILE_SIZE;
 
-    if (D_flag) {
-        ibuf = (char *)ALLOC_ALIGNED(INIT_BUFSZ);
-    }
-    else {
-        ibuf = (char*)malloc(INIT_BUFSZ);
-    }
+    ibuf = (char*)malloc(INIT_BUFSZ);
     memset(ibuf, ':', INIT_BUFSZ);
 
     SEEK(fd, 0L);
@@ -615,35 +600,21 @@ int do_open(int flag)
 {
     if ((f_fd = OPEN(filename, flag)) == INVALID_HANDLE) {
        perror("shared file create");
-       if (!flag)      /* Only exit if the first open fails */
-           exit(1);
-       closed = 0;
        return FAIL;
        /*NOTREACHED*/
     }
 
-    closed = 0;
-
-#ifdef __sun
-    if (D_flag) {
-        directio(f_fd, DIRECTIO_ON);
-    }
-#elif defined(__APPLE__)
-    if (D_flag) {
-       fcntl(f_fd, F_NOCACHE, 1);
-    }
-#endif
     return PASS;
 }
 
-int do_lock(int type, int start, int length)
+static int do_lock(int cmd, int type, int start, int length)
 {
     int ret;
     int filedes = f_fd;
     struct flock fl;
 
     if(debug > 1) {
-       fprintf(stderr, "do_lock: start=%d, length=%d\n", start, length);
+       fprintf(stderr, "do_lock: cmd=%d type=%d start=%d, length=%d\n", cmd, type, start, length);
     }
 
     if (f_fd < 0)
@@ -657,7 +628,7 @@ int do_lock(int type, int start, int length)
 
     errno = 0;
 
-    ret = fcntl(filedes, F_SETLK, &fl);
+    ret = fcntl(filedes, cmd, &fl);
     saved_errno = errno;           
 
     if(debug > 1 && ret)
@@ -666,35 +637,6 @@ int do_lock(int type, int start, int length)
     return(ret==0?PASS:FAIL);
 }
 
-int do_unlock(int start, int length)
-{
-    int ret;
-    int filedes = f_fd;
-    struct flock fl;
-
-    if(debug > 1) {
-       fprintf(stderr, "do_unlock: start=%d, length=%d\n", start, length);
-    }
-
-    if (f_fd < 0)
-       return f_fd;
-    
-    fl.l_start = start;
-    fl.l_len = length;
-    fl.l_whence = SEEK_SET;
-    fl.l_pid = getpid();
-    fl.l_type = F_UNLCK;
-
-    errno = 0;
-
-    ret = fcntl(filedes, F_SETLK, &fl);
-    saved_errno = errno;           
-    if(debug > 1 && ret)
-       fprintf(stderr, "do_lock: ret = %d, errno = %d (%s)\n", ret, errno, strerror(errno));
-
-    return(ret==0?PASS:FAIL);
-}
-
 int do_close(void)
 {      
     if(debug > 1) {
@@ -703,12 +645,13 @@ int do_close(void)
 
     errno =0;
     CLOSE(f_fd);
+    f_fd = INVALID_HANDLE;
 
     saved_errno = errno;           
        
     if (errno)
        return FAIL;
-    return(PASS);
+    return PASS;
 }
 
 void
@@ -741,7 +684,7 @@ send_ctl(void)
         if (nwrite < 0)
             perror("send_ctl: write");
         else
-            fprintf(stderr, "send_ctl[%d]: write() returns %d, not %lu as expected\n", 
+            fprintf(stderr, "send_ctl[%d]: write() returns %d, not %zu as expected\n", 
                     ctl.test, nwrite, sizeof(ctl));
         exit(1);
         /*NOTREACHED*/
@@ -756,7 +699,7 @@ void recv_ctl(void)
         if (nread < 0)
             perror("recv_ctl: read");
         else {
-            fprintf(stderr, "recv_ctl[%d]: read() returns %d, not %lu as expected\n", 
+            fprintf(stderr, "recv_ctl[%d]: read() returns %d, not %zu as expected\n", 
                     ctl.test, nread, sizeof(ctl));
            fprintf(stderr, "socket might has been closed by other locktest\n");
        } 
@@ -780,7 +723,7 @@ void recv_ctl(void)
 void
 cleanup(void)
 {
-    if (f_fd>=0 && !reopen && !closed)
+    if (f_fd>=0)
         CLOSE(f_fd);
     
     if (c_fd>=0)
@@ -805,7 +748,6 @@ main(int argc, char *argv[])
     char       *p;
     extern char        *optarg;
     extern int optind;
-    extern int errno;
     int fail_count = 0;; 
     
     atexit(cleanup);
@@ -858,25 +800,8 @@ main(int argc, char *argv[])
     }
 
     filename=argv[optind];
-    do_open(0);
-
-    /*
-     * +10 is slop for the iteration number if do_write() ... never
-     * needed unless maxio is very small
-     */
-    if (D_flag) {
-        if ((buf = (char *)ALLOC_ALIGNED(maxio + 10)) == NULL) {
-           perror("aligned alloc buf");
-           exit(1);
-           /*NOTREACHED*/
-        }
-    } else {
-        if ((buf = (char *)malloc(maxio + 10)) == NULL) {
-           perror("malloc buf");
-           exit(1);
-           /*NOTREACHED*/
-        }
-    }
+    if (do_open(O_RDWR) == FAIL)
+       exit(1);
 
     setbuf(stderr, NULL);
 
@@ -925,6 +850,20 @@ main(int argc, char *argv[])
            /*NOTREACHED*/
        }
 
+       if (port == 0) {
+               socklen_t addr_len = sizeof(myAddr);
+
+               if (getsockname(s_fd, &myAddr, &addr_len)) {
+                   perror("getsockname");
+                   exit(1);
+               }
+
+               port = ntohs(myAddr.sin_port);
+       }
+
+       printf("server port: %d\n", port);
+       fflush(stdout);
+
        c_fd = accept(s_fd, NULL, NULL);
        if (c_fd == INVALID_SOCKET) {
            perror("accept");
@@ -1021,13 +960,13 @@ main(int argc, char *argv[])
                if(tests[index][TEST_NUM] != 0) {
                    switch(tests[index][COMMAND]) {
                        case WRLOCK:
-                           result = do_lock(F_WRLCK, tests[index][OFFSET], tests[index][LENGTH]);
+                           result = do_lock(F_SETLK, F_WRLCK, tests[index][OFFSET], tests[index][LENGTH]);
                            break;
                        case RDLOCK:
-                           result = do_lock(F_RDLCK, tests[index][OFFSET], tests[index][LENGTH]);
+                           result = do_lock(F_SETLK, F_RDLCK, tests[index][OFFSET], tests[index][LENGTH]);
                            break;
                        case UNLOCK:
-                           result = do_unlock(tests[index][OFFSET], tests[index][LENGTH]);
+                           result = do_lock(F_SETLK, F_UNLCK, tests[index][OFFSET], tests[index][LENGTH]);
                            break;
                        case F_CLOSE:
                            result = do_close();
@@ -1035,6 +974,12 @@ main(int argc, char *argv[])
                        case F_OPEN:
                            result = do_open(tests[index][FLAGS]);
                            break;
+                       case WRTEST:
+                           result = do_lock(F_GETLK, F_WRLCK, tests[index][OFFSET], tests[index][LENGTH]);
+                           break;
+                       case RDTEST:
+                           result = do_lock(F_GETLK, F_RDLCK, tests[index][OFFSET], tests[index][LENGTH]);
+                           break;
                    }
                    if( result != tests[index][RESULT]) {
                        fail_flag++;
@@ -1091,10 +1036,6 @@ main(int argc, char *argv[])
                    }
                }
            }
-           if (debug > 1) {
-               fprintf(stderr, "server sleeping ...\n");
-               SLEEP(1);
-           }
            if(tests[index][TEST_NUM] != 0) {
                if(last_test != tests[index][TEST_NUM]) {
                    test_count++;
@@ -1131,13 +1072,13 @@ main(int argc, char *argv[])
            ctl.length = tests[index][LENGTH];
            switch(tests[index][COMMAND]) {
                case WRLOCK:
-                   result = do_lock(F_WRLCK, tests[index][OFFSET], tests[index][LENGTH]);
+                   result = do_lock(F_SETLK, F_WRLCK, tests[index][OFFSET], tests[index][LENGTH]);
                    break;
                case RDLOCK:
-                   result = do_lock(F_RDLCK, tests[index][OFFSET], tests[index][LENGTH]);
+                   result = do_lock(F_SETLK, F_RDLCK, tests[index][OFFSET], tests[index][LENGTH]);
                    break;
                case UNLOCK:
-                   result = do_unlock(tests[index][OFFSET], tests[index][LENGTH]);
+                   result = do_lock(F_SETLK, F_UNLCK, tests[index][OFFSET], tests[index][LENGTH]);
                    break;
                case F_CLOSE:
                    result = do_close();
@@ -1145,6 +1086,12 @@ main(int argc, char *argv[])
                case F_OPEN:
                    result = do_open(tests[index][FLAGS]);
                    break;
+               case WRTEST:
+                   result = do_lock(F_GETLK, F_WRLCK, tests[index][OFFSET], tests[index][LENGTH]);
+                   break;
+               case RDTEST:
+                   result = do_lock(F_GETLK, F_RDLCK, tests[index][OFFSET], tests[index][LENGTH]);
+                   break;
            }
            if( result != tests[index][RESULT] ) {
                if(debug)
@@ -1170,13 +1117,6 @@ main(int argc, char *argv[])
     if(server)
        printf("%d tests run, %d failed\n", test_count, fail_count);
 }   
-    if (buf) {
-        if (D_flag)
-            FREE_ALIGNED(buf);
-        else
-            free(buf);
-    }
-
     
     exit(fail_count);
     /*NOTREACHED*/