Whamcloud - gitweb
LU-13960 tests: correct usage of _var variable
[fs/lustre-release.git] / lustre / tests / group_lock_test.c
index 13338df..f20010d 100644 (file)
@@ -21,7 +21,7 @@
  */
 
 /*
- * Copyright 2014 Cray Inc, all rights reserved.
+ * Copyright 2014, 2015 Cray Inc, all rights reserved.
  * Author: Frank Zago.
  *
  * A few portions are extracted from llapi_layout_test.c
 #include <errno.h>
 #include <getopt.h>
 #include <fcntl.h>
+#include <sys/ioctl.h>
 #include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/uio.h>
 #include <sys/stat.h>
+#include <time.h>
 #include <unistd.h>
 #include <poll.h>
 
 #include <lustre/lustreapi.h>
-#include <lustre/lustre_idl.h>
 
 #define ERROR(fmt, ...)                                                        \
        fprintf(stderr, "%s: %s:%d: %s: " fmt "\n",                     \
 
 #define PERFORM(testfn) \
        do {                                                            \
+               cleanup();                                              \
                fprintf(stderr, "Starting test " #testfn " at %lld\n",  \
                        (unsigned long long)time(NULL));                \
                testfn();                                               \
                fprintf(stderr, "Finishing test " #testfn " at %lld\n", \
                        (unsigned long long)time(NULL));                \
+               cleanup();                                              \
        } while (0)
 
 /* Name of file/directory. Will be set once and will not change. */
@@ -92,8 +97,6 @@ static void test10(void)
        int gid;
        int i;
 
-       cleanup();
-
        /* Create the test file, and open it. */
        fd = creat(mainpath, 0);
        ASSERTF(fd >= 0, "creat failed for '%s': %s",
@@ -166,8 +169,6 @@ static void test11(void)
        int gid;
        char buf[10000];
 
-       cleanup();
-
        /* Create the test file. */
        fd = creat(mainpath, 0);
        ASSERTF(fd >= 0, "creat failed for '%s': %s",
@@ -226,8 +227,58 @@ static void test11(void)
 
                close(fd);
        }
+}
 
-       cleanup();
+/* Lock / unlock a volatile file, with different creation flags */
+static void test12(void)
+{
+       int rc;
+       int fd;
+       int gid;
+
+       rc = mkdir(mainpath, 0600);
+       ASSERTF(rc == 0, "mkdir failed for '%s': %s",
+               mainpath, strerror(errno));
+
+       fd = llapi_create_volatile_idx(mainpath, -1, O_CREAT | O_WRONLY);
+       ASSERTF(fd >= 0, "llapi_create_volatile_idx failed on '%s': %s",
+               mainpath, strerror(-fd));
+
+       gid = 34895;
+       rc = llapi_group_lock(fd, gid);
+       ASSERTF(rc == 0, "cannot lock '%s': %s", mainpath, strerror(-rc));
+
+       rc = llapi_group_unlock(fd, gid);
+       ASSERTF(rc == 0, "cannot unlock '%s': %s", mainpath, strerror(-rc));
+
+       close(fd);
+
+       fd = llapi_create_volatile_idx(mainpath, -1,
+                                      O_CREAT | O_WRONLY | O_LOV_DELAY_CREATE);
+       ASSERTF(fd >= 0, "llapi_create_volatile_idx failed on '%s': %s",
+               mainpath, strerror(-fd));
+
+       gid = 3354895;
+       rc = llapi_group_lock(fd, gid);
+       ASSERTF(rc == 0, "cannot lock '%s': %s", mainpath, strerror(-rc));
+
+       rc = llapi_group_unlock(fd, gid);
+       ASSERTF(rc == 0, "cannot unlock '%s': %s", mainpath, strerror(-rc));
+
+       close(fd);
+
+       fd = llapi_create_volatile_idx(mainpath, -1, O_RDONLY);
+       ASSERTF(fd >= 0, "llapi_create_volatile_idx failed on '%s': %s",
+               mainpath, strerror(-fd));
+
+       gid = 3489655;
+       rc = llapi_group_lock(fd, gid);
+       ASSERTF(rc == 0, "cannot lock '%s': %s", mainpath, strerror(-rc));
+
+       rc = llapi_group_unlock(fd, gid);
+       ASSERTF(rc == 0, "cannot unlock '%s': %s", mainpath, strerror(-rc));
+
+       close(fd);
 }
 
 static void helper_test20(int fd)
@@ -263,8 +314,6 @@ static void test20(void)
        int rc;
        char dname[PATH_MAX];
 
-       cleanup();
-
        /* Try the mountpoint. Should fail. */
        fd = open(fsmountdir, O_RDONLY | O_DIRECTORY);
        ASSERTF(fd >= 0, "open failed for '%s': %s", mainpath, strerror(errno));
@@ -282,7 +331,7 @@ static void test20(void)
 
        /* A regular directory. */
        rc = mkdir(mainpath, 0600);
-       ASSERTF(fd >= 0, "mkdir failed for '%s': %s",
+       ASSERTF(rc == 0, "mkdir failed for '%s': %s",
                mainpath, strerror(errno));
 
        fd = open(mainpath, O_RDONLY | O_DIRECTORY);
@@ -301,8 +350,6 @@ static void test30(void)
        int gid2;
        int rc;
 
-       cleanup();
-
        /* Create the test file, and open it. */
        fd1 = creat(mainpath, 0);
        ASSERTF(fd1 >= 0, "open failed for '%s': %s",
@@ -375,6 +422,63 @@ static void test30(void)
        close(fd2);
 }
 
+/* Test locking between several fds. */
+static void test40(void)
+{
+       int rc;
+       int fd;
+       int gid;
+       char buf[10000];
+       int i, j, threads = 40;
+
+       /* Create the test file. */
+       fd = open(mainpath, O_RDWR | O_CREAT | O_TRUNC,
+                 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+       ASSERTF(fd >= 0, "creat failed for '%s': %s",
+               mainpath, strerror(errno));
+       /* Lock */
+       gid = 1234;
+       rc = ioctl(fd, LL_IOC_GROUP_LOCK, gid);
+       ASSERTF(rc == 0, "cannot lock '%s' gid %d: %s", mainpath, gid,
+               strerror(errno));
+
+       for (i = 0; i < threads; i++) {
+               rc = fork();
+               ASSERTF(rc >= 0, "fork failed %s", strerror(errno));
+
+               if (rc == 0) {
+                       struct iovec io = { .iov_base = buf,
+                                           .iov_len = sizeof(buf)};
+
+                       /* writing to a fixed offset */
+                       memset(buf, i, sizeof(buf));
+                       rc = pwritev(fd, &io, 1, sizeof(buf) * i);
+                       ASSERTF(rc == sizeof(buf), "write failed for '%s' block %d: %s",
+                               mainpath, i, strerror(errno));
+
+                       close(fd);
+                       exit(0);
+               }
+       }
+
+       while ((i = wait(&rc)) > 0);
+
+       /* Check data */
+       for (i = 0; i < threads; i++) {
+               rc = read(fd, buf, sizeof(buf));
+               ASSERTF(rc == sizeof(buf), "read failed for '%s': %s",
+                       mainpath, strerror(errno));
+               for (j = 0; j < rc; j++)
+                       ASSERTF(i == buf[j], "wrong data at off %d %d != %d",
+                               j, i, buf[j]);
+       }
+
+       /* close unlock group lock */
+       rc = close(fd);
+       ASSERTF(rc == 0, "close failed '%s': %s",
+               mainpath, strerror(errno));
+}
+
 static void usage(char *prog)
 {
        fprintf(stderr, "Usage: %s [-d lustre_dir]\n", prog);
@@ -401,7 +505,7 @@ static void process_args(int argc, char *argv[])
 
 int main(int argc, char *argv[])
 {
-       char fsname[8];
+       char fsname[8 + 1];
        int rc;
 
        process_args(argc, argv);
@@ -428,8 +532,10 @@ int main(int argc, char *argv[])
 
        PERFORM(test10);
        PERFORM(test11);
+       PERFORM(test12);
        PERFORM(test20);
        PERFORM(test30);
+       PERFORM(test40);
 
        return EXIT_SUCCESS;
 }