src/locktest: Remove unnecessary sleep
[xfstests-dev.git] / src / locktest.c
index fa6ea66c28d0d8ac6c3d2cfd5a57113763ca774e..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
  */
 
 /*
@@ -44,6 +32,8 @@
 #define PLATFORM_CLEANUP()  /*no-op*/
 #define LL                  "ll"
 
+extern int h_errno;
+
 #define inet_aton(STRING, INADDRP) \
     (((INADDRP)->s_addr = inet_addr(STRING)) == -1 ? 0 : 1)
 
@@ -71,8 +61,7 @@
        
 #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))
@@ -80,7 +69,6 @@
 
 #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))
@@ -92,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
@@ -178,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 */
 
@@ -510,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},
@@ -582,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);
@@ -613,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)
@@ -655,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)
@@ -664,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) {
@@ -701,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
@@ -716,7 +661,7 @@ send_ctl(void)
 
     if (debug > 1) {
        fprintf(stderr, "send_ctl: test=%d, command=%d offset=%"LL"d, length=%"LL"d, result=%d, error=%d\n", 
-                ctl.test, ctl.command, ctl.offset, ctl.length,ctl.result, ctl.error);
+                ctl.test, ctl.command, (long long)ctl.offset, (long long)ctl.length,ctl.result, ctl.error);
     }
 
     ctl.test= bswap_uint32(ctl.test);
@@ -739,7 +684,7 @@ send_ctl(void)
         if (nwrite < 0)
             perror("send_ctl: write");
         else
-            fprintf(stderr, "send_ctl[%d]: write() returns %d, not %d as expected\n", 
+            fprintf(stderr, "send_ctl[%d]: write() returns %d, not %zu as expected\n", 
                     ctl.test, nwrite, sizeof(ctl));
         exit(1);
         /*NOTREACHED*/
@@ -754,7 +699,7 @@ void recv_ctl(void)
         if (nread < 0)
             perror("recv_ctl: read");
         else {
-            fprintf(stderr, "recv_ctl[%d]: read() returns %d, not %d 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");
        } 
@@ -771,14 +716,14 @@ void recv_ctl(void)
 
     if (debug > 1) {
        fprintf(stderr, "recv_ctl: test=%d, command=%d offset=%"LL"d, length=%"LL"d, result=%d, error=%d\n", 
-                ctl.test, ctl.command, ctl.offset, ctl.length, ctl.result, ctl.error);
+                ctl.test, ctl.command, (long long)ctl.offset, (long long)ctl.length, ctl.result, ctl.error);
     }
 }
 
 void
 cleanup(void)
 {
-    if (f_fd>=0 && !reopen && !closed)
+    if (f_fd>=0)
         CLOSE(f_fd);
     
     if (c_fd>=0)
@@ -797,13 +742,12 @@ main(int argc, char *argv[])
     int                c;
     struct sockaddr_in myAddr;
     struct linger      noLinger = {1, 0};
-    char       *host;
+    char       *host = NULL;
     char       *endnum;
     int                errflag = 0;
     char       *p;
     extern char        *optarg;
     extern int optind;
-    extern int errno;
     int fail_count = 0;; 
     
     atexit(cleanup);
@@ -856,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);
 
@@ -923,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");
@@ -937,7 +878,10 @@ main(int argc, char *argv[])
         struct hostent  *servInfo;
 
         if ((servInfo = gethostbyname(host)) == NULL) {
-            perror("gethostbyname");
+           printf("Couldn't get hostbyname for %s", host);
+           if (h_errno == HOST_NOT_FOUND)
+               printf(": host not found");
+           printf("\n");
             exit(1);
             /*NOTREACHED*/
         }
@@ -1016,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();
@@ -1030,19 +974,27 @@ 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++;
                        /* We have a failure */
                        if(debug)
-                           fprintf(stderr, "Server failure in test %d, while %sing using offset %llu, length %llu - err = %d:%s\n", 
+                           fprintf(stderr, "Server failure in test %d, while %sing using offset %lld, length %lld - err = %d:%s\n", 
                                        ctl.test, tests[index][COMMAND]==WRLOCK?"write lock":
                                                tests[index][COMMAND]==RDLOCK?"read lock":
                                                tests[index][COMMAND]==UNLOCK?"unlock":
                                                tests[index][COMMAND]==F_OPEN?"open":"clos", 
-                                               tests[index][OFFSET], tests[index][LENGTH], saved_errno, strerror(saved_errno));
-                       fprintf(stderr, "Server failure in %llu:%s\n",
-                                       tests[index][TEST_NUM],
+                                               (long long)tests[index][OFFSET],
+                                               (long long)tests[index][LENGTH],
+                                               saved_errno, strerror(saved_errno));
+                       fprintf(stderr, "Server failure in %lld:%s\n",
+                                       (long long)tests[index][TEST_NUM],
                                        descriptions[tests[index][TEST_NUM] - 1]);
                    }
                }
@@ -1053,12 +1005,13 @@ main(int argc, char *argv[])
                    end=1;
                } 
                if(debug > 1)
-                   fprintf(stderr, "Sending command to client (%d) - %s - %llu:%llu\n", 
+                   fprintf(stderr, "Sending command to client (%d) - %s - %lld:%lld\n", 
                                        index, tests[index][COMMAND]==WRLOCK?"write lock":
                                        tests[index][COMMAND]==RDLOCK?"read lock":
                                        tests[index][COMMAND]==UNLOCK?"unlock": 
                                        tests[index][COMMAND]==F_OPEN?"open":"clos", 
-                                       tests[index][OFFSET], tests[index][LENGTH]);
+                                       (long long)tests[index][OFFSET],
+                                       (long long)tests[index][LENGTH]);
                /* get the client to do something */
                ctl.index = index;
                send_ctl();
@@ -1070,22 +1023,19 @@ main(int argc, char *argv[])
                    if( ctl.result == FAIL ) {
                        fail_flag++;
                        if(debug)
-                           fprintf(stderr, "Client failure in test %d, while %sing using offset %llu, length %llu - err = %d:%s\n",
+                           fprintf(stderr, "Client failure in test %d, while %sing using offset %lld, length %lld - err = %d:%s\n",
                                        ctl.test, ctl.command==WRLOCK?"write lock":
                                        ctl.command==RDLOCK?"read lock":
                                        ctl.command==UNLOCK?"unlock":
                                        ctl.command==F_OPEN?"open":"clos",
-                                       ctl.offset, ctl.length, ctl.error, strerror(ctl.error));
-                       fprintf(stderr, "Client failure in %llu:%s\n",
-                                       tests[index][TEST_NUM],
+                                       (long long)ctl.offset, (long long)ctl.length,
+                                       ctl.error, strerror(ctl.error));
+                       fprintf(stderr, "Client failure in %lld:%s\n",
+                                       (long long)tests[index][TEST_NUM],
                                        descriptions[tests[index][TEST_NUM] - 1]);
                    }
                }
            }
-           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++;
@@ -1122,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();
@@ -1136,10 +1086,17 @@ 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)
-                   fprintf(stderr,"Got %d, wanted %llu\n", result, tests[index][RESULT]);
+                   fprintf(stderr,"Got %d, wanted %lld\n", result,
+                                       (long long)tests[index][RESULT]);
                ctl.result = FAIL;
                ctl.error = saved_errno;
                fail_count++;
@@ -1160,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*/