diff options
Diffstat (limited to 'tests/basic/gfapi/mandatory-lock-optimal.c')
| -rw-r--r-- | tests/basic/gfapi/mandatory-lock-optimal.c | 532 |
1 files changed, 532 insertions, 0 deletions
diff --git a/tests/basic/gfapi/mandatory-lock-optimal.c b/tests/basic/gfapi/mandatory-lock-optimal.c new file mode 100644 index 00000000000..34fef8d0b80 --- /dev/null +++ b/tests/basic/gfapi/mandatory-lock-optimal.c @@ -0,0 +1,532 @@ +/* Pre-requisites:- + * + * 1. Make sure that performance translators are switched off while running this + * test. + * 2. Perform the following volume set operation: + * # gluster volume set <VOLNAME> locks.mandatory-locking optimal + * 3. For installation under non-standard paths, export LD_LIBRARY_PATH to + * automatically load exact libgfapi.so and compile this C file as follows: + * $ gcc mandatory-lock-optimal.c -lgfapi -I <include path for api/glfs.h> -L + * <include path for libgfapi shared library> + */ + +#include <errno.h> +#include <stdio.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <glusterfs/api/glfs.h> + +#define TOTAL_TEST_COUNT 8 + +/* C1 = Client 1 : C2 = Client 2 : C3 = Client 3 : + * fs1, fd1 are associated with C1. Similarly fs2, fd2 for C2 + * and fs3, fd3 for C3 */ + +FILE *fp; +glfs_t *fs1, *fs2, *fs3; +glfs_fd_t *fd, *fd1, *fd2, *fd3; +struct flock lock; +char buf1[10], *buf2 = "ten bytes!", *fname = "/mand.lock"; +int ret, test_count; +off_t offset; + +/* run_test_1 () : C1 takes byte range mandatory read lock. + C2 attempts to read from a conflicting range. + Expected result : Read from C2 should pass. + + * run_test_2 () : C1 takes byte range mandatory read lock. + C2 attempts write to a conflicting range. + Expected result : Write from C2 should fail with EAGAIN. + + * run_test_3 () : C1 takes byte range advisory write lock. + C2 attempts to read from a conflicting range. + Expected result : Read from C2 should pass. + + * run_test_4 () : C1 takes byte range advisory write lock. + C2 attempts write to a conflicting range. + Expected result : Write from C2 should pass. + + * run_test_5 () : C1 takes byte range advisory read lock. + C2 attempts to open the same file with O_TRUNC. + Expected result : Open from C2 should pass. + + * run_test_6 () : C1 takes byte range mandatory read lock. + C2 attempts to open the same file with O_TRUNC. + Expected result : Open from C2 should fail with EAGAIN. + + * run_test_7 () : C1 takes byte range mandatory read lock. + C2 attempts ftruncate on a conflicting range. + Expected result : Write from C2 should fail with EAGAIN. + + * run_test_8 () : C1 takes byte range advisory read lock. + C2 takes byte range mandatory read lock + within the byte range for which C1 already + holds an advisory lock so as to perform a + basic split/merge. C3 repositions fd3 to + start of C2's byte range mandatory lock + offset and attempts a write. Then it again + repositions fd3 to one byte past C2's byte + range mandatoy lock and again attempts a write. + Expected result : First write should fail with EAGAIN. + Second write should pass. */ + +#define LOG_ERR(func, err) \ + do { \ + if (!fp) \ + fprintf(stderr, "\n%s : returned error (%s)\n", func, \ + strerror(err)); \ + else \ + fprintf(fp, "\n%s : returned error (%s)\n", func, strerror(err)); \ + cleanup_and_exit(err); \ + } while (0) + +void +cleanup_and_exit(int exit_status) +{ + if (exit_status || test_count != TOTAL_TEST_COUNT) { + fprintf(fp, "\nAborting due to some test failures.\n"); + exit_status = 1; + } else + fprintf(fp, "\nAll tests ran successfully.\n"); + if (fp) + fclose(fp); + if (fd) + glfs_close(fd); + if (fd1) + glfs_close(fd1); + if (fd2) + glfs_close(fd2); + + glfs_unlink(fs1, fname); + + if (fs1) + glfs_fini(fs1); + if (fs2) + glfs_fini(fs2); + + exit(exit_status); +} + +glfs_t * +new_client_create(char *hostname, char *volname, char *logfile_name) +{ + glfs_t *fs = NULL; + + fs = glfs_new(volname); + if (!fs) + LOG_ERR("glfs_new", errno); + + ret = glfs_set_volfile_server(fs, "tcp", hostname, 24007); + if (ret) + LOG_ERR("glfs_set_volfile_server", errno); + + ret = glfs_set_logging(fs, logfile_name, 7); + if (ret) + LOG_ERR("glfs_set_logging", errno); + + ret = glfs_init(fs); + if (ret) + LOG_ERR("glfs_init", errno); + + return fs; +} + +void +run_test_1(int i) +{ + fprintf(fp, "\nRunning Test-%d . . . ", i); + + fd1 = glfs_open(fs1, fname, O_RDONLY | O_NONBLOCK); + if (!fd1) + LOG_ERR("glfs_open", errno); + + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0L; + lock.l_len = 5L; + + ret = glfs_file_lock(fd1, F_SETLK, &lock, GLFS_LK_MANDATORY); + if (ret) + LOG_ERR("glfs_file_lock", errno); + + fd2 = glfs_open(fs2, fname, O_RDONLY | O_NONBLOCK); + if (!fd2) + LOG_ERR("glfs_open", errno); + + /* On successful read, 0 is returned as there is no content inside the + * file + */ + ret = glfs_read(fd2, buf1, 10, 0); + if (ret) + LOG_ERR("glfs_read", errno); + + ret = glfs_close(fd1); + if (ret) + LOG_ERR("glfs_close", errno); + fd1 = NULL; + + ret = glfs_close(fd2); + if (ret) + LOG_ERR("glfs_close", errno); + fd2 = NULL; + + test_count++; + fprintf(fp, "OK\n", i); +} + +void +run_test_2(int i) +{ + fprintf(fp, "\nRunning Test-%d . . . ", i); + + fd1 = glfs_open(fs1, fname, O_RDONLY | O_NONBLOCK); + if (!fd1) + LOG_ERR("glfs_open", errno); + + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0L; + lock.l_len = 5L; + + ret = glfs_file_lock(fd1, F_SETLK, &lock, GLFS_LK_MANDATORY); + if (ret) + LOG_ERR("glfs_file_lock", errno); + + fd2 = glfs_open(fs2, fname, O_WRONLY | O_NONBLOCK); + if (!fd2) + LOG_ERR("glfs_open", errno); + + ret = glfs_write(fd2, buf2, 10, 0); + if (ret == 10 || errno != EAGAIN) + LOG_ERR("glfs_write", errno); + + ret = glfs_close(fd1); + if (ret) + LOG_ERR("glfs_close", errno); + fd1 = NULL; + + ret = glfs_close(fd2); + if (ret) + LOG_ERR("glfs_close", errno); + fd2 = NULL; + + test_count++; + fprintf(fp, "OK\n", i); +} + +void +run_test_3(int i) +{ + fprintf(fp, "\nRunning Test-%d . . . ", i); + + fd1 = glfs_open(fs1, fname, O_WRONLY | O_NONBLOCK); + if (!fd1) + LOG_ERR("glfs_open", errno); + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0L; + lock.l_len = 5L; + + ret = glfs_file_lock(fd1, F_SETLK, &lock, GLFS_LK_ADVISORY); + if (ret) + LOG_ERR("glfs_file_lock", errno); + + fd2 = glfs_open(fs2, fname, O_RDONLY | O_NONBLOCK); + if (!fd2) + LOG_ERR("glfs_open", errno); + + /* Still there is no content inside file. So following read should + * return 0 + */ + ret = glfs_read(fd2, buf1, 10, 0); + if (ret) + LOG_ERR("glfs_read", errno); + + ret = glfs_close(fd1); + if (ret) + LOG_ERR("glfs_close", errno); + fd1 = NULL; + + ret = glfs_close(fd2); + if (ret) + LOG_ERR("glfs_close", errno); + fd2 = NULL; + + test_count++; + fprintf(fp, "OK\n", i); +} + +void +run_test_4(int i) +{ + fprintf(fp, "\nRunning Test-%d . . . ", i); + + fd1 = glfs_open(fs1, fname, O_WRONLY | O_NONBLOCK); + if (!fd1) + LOG_ERR("glfs_open", errno); + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0L; + lock.l_len = 5L; + + ret = glfs_file_lock(fd1, F_SETLK, &lock, GLFS_LK_ADVISORY); + if (ret) + LOG_ERR("glfs_file_lock", errno); + + fd2 = glfs_open(fs2, fname, O_WRONLY | O_NONBLOCK); + if (!fd2) + LOG_ERR("glfs_open", errno); + + ret = glfs_write(fd2, buf2, 10, 0); + if (ret != 10) + LOG_ERR("glfs_write", errno); + + ret = glfs_close(fd1); + if (ret) + LOG_ERR("glfs_close", errno); + fd1 = NULL; + + ret = glfs_close(fd2); + if (ret) + LOG_ERR("glfs_close", errno); + fd2 = NULL; + + test_count++; + fprintf(fp, "OK\n", i); +} + +void +run_test_5(int i) +{ + fprintf(fp, "\nRunning Test-%d . . . ", i); + + fd1 = glfs_open(fs1, fname, O_RDONLY | O_NONBLOCK); + if (!fd1) + LOG_ERR("glfs_open", errno); + + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0L; + lock.l_len = 5L; + + ret = glfs_file_lock(fd1, F_SETLK, &lock, GLFS_LK_ADVISORY); + if (ret) + LOG_ERR("glfs_file_lock", errno); + + fd2 = glfs_open(fs2, fname, O_RDONLY | O_NONBLOCK | O_TRUNC); + if (!fd2) + LOG_ERR("glfs_open", errno); + + ret = glfs_close(fd1); + if (ret) + LOG_ERR("glfs_close", errno); + fd1 = NULL; + + ret = glfs_close(fd2); + if (ret) + LOG_ERR("glfs_close", errno); + fd2 = NULL; + + test_count++; + fprintf(fp, "OK\n", i); +} + +void +run_test_6(int i) +{ + fprintf(fp, "\nRunning Test-%d . . . ", i); + + fd1 = glfs_open(fs1, fname, O_RDONLY | O_NONBLOCK); + if (!fd1) + LOG_ERR("glfs_open", errno); + + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0L; + lock.l_len = 5L; + + ret = glfs_file_lock(fd1, F_SETLK, &lock, GLFS_LK_MANDATORY); + if (ret) + LOG_ERR("glfs_file_lock", errno); + + fd2 = glfs_open(fs2, fname, O_RDONLY | O_NONBLOCK | O_TRUNC); + if (fd2) + LOG_ERR("glfs_open", errno); + + ret = glfs_close(fd1); + if (ret) + LOG_ERR("glfs_close", errno); + fd1 = NULL; + + test_count++; + fprintf(fp, "OK\n", i); +} + +void +run_test_7(int i) +{ + fprintf(fp, "\nRunning Test-%d . . . ", i); + + fd1 = glfs_open(fs1, fname, O_RDONLY | O_NONBLOCK); + if (!fd1) + LOG_ERR("glfs_open", errno); + + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0L; + lock.l_len = 5L; + + ret = glfs_file_lock(fd1, F_SETLK, &lock, GLFS_LK_MANDATORY); + if (ret) + LOG_ERR("glfs_file_lock", errno); + + fd2 = glfs_open(fs2, fname, O_RDWR | O_NONBLOCK); + if (!fd2) + LOG_ERR("glfs_open", errno); + + ret = glfs_ftruncate(fd2, 4, NULL, NULL); + if (ret == 0 || errno != EAGAIN) + LOG_ERR("glfs_ftruncate", errno); + + ret = glfs_close(fd1); + if (ret) + LOG_ERR("glfs_close", errno); + fd1 = NULL; + + ret = glfs_close(fd2); + if (ret) + LOG_ERR("glfs_close", errno); + fd2 = NULL; + + test_count++; + fprintf(fp, "OK\n", i); +} + +void +run_test_8(int i) +{ + fprintf(fp, "\nRunning Test-%d . . . ", i); + + fd1 = glfs_open(fs1, fname, O_RDONLY | O_NONBLOCK); + if (!fd1) + LOG_ERR("glfs_open", errno); + + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0L; + lock.l_len = 10L; + + ret = glfs_file_lock(fd1, F_SETLK, &lock, GLFS_LK_ADVISORY); + if (ret) + LOG_ERR("glfs_file_lock", errno); + + fd2 = glfs_open(fs2, fname, O_RDONLY | O_NONBLOCK); + if (!fd2) + LOG_ERR("glfs_open", errno); + + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 5L; + lock.l_len = 2L; + + ret = glfs_file_lock(fd2, F_SETLK, &lock, GLFS_LK_MANDATORY); + if (ret) + LOG_ERR("glfs_file_lock", errno); + + fd3 = glfs_open(fs3, fname, O_RDWR | O_NONBLOCK); + if (!fd3) + LOG_ERR("glfs_open", errno); + + offset = glfs_lseek(fd3, 5L, SEEK_SET); + if (offset != 5) + LOG_ERR("glfs_lseek", errno); + + ret = glfs_write(fd3, buf2, 10, 0); + if (ret == 10 || errno != EAGAIN) + LOG_ERR("glfs_write", errno); + + offset = glfs_lseek(fd3, 8L, SEEK_SET); + if (offset != 8) + LOG_ERR("glfs_lseek", errno); + + ret = glfs_write(fd3, buf2, 10, 0); + if (ret != 10) + LOG_ERR("glfs_write", errno); + + ret = glfs_close(fd1); + if (ret) + LOG_ERR("glfs_close", errno); + fd1 = NULL; + + ret = glfs_close(fd2); + if (ret) + LOG_ERR("glfs_close", errno); + fd2 = NULL; + + ret = glfs_close(fd3); + if (ret) + LOG_ERR("glfs_close", errno); + fd3 = NULL; + + test_count++; + fprintf(fp, "OK\n", i); +} + +int +main(int argc, char *argv[]) +{ + char logfile[50]; + + if (argc != 4) { + fprintf(stderr, + "Usage: %s <server ip/hostname> <volume name> <test log " + "directory>\n", + argv[0]); + return 0; + } + + sprintf(logfile, "%s/%s", argv[3], "mandatory-lock-optimal-test.log"); + fp = fopen(logfile, "w"); + if (!fp) { + fprintf(stderr, "\n%s\n", logfile); + LOG_ERR("Log file creation", errno); + } + + sprintf(logfile, "%s/%s", argv[3], "glfs-client-1.log"); + fs1 = new_client_create(argv[1], argv[2], logfile); + if (!fs1) + LOG_ERR("client-1 creation", EINVAL); + + sprintf(logfile, "%s/%s", argv[3], "glfs-client-2.log"); + fs2 = new_client_create(argv[1], argv[2], logfile); + if (!fs2) + LOG_ERR("client-2 creation", EINVAL); + + sprintf(logfile, "%s/%s", argv[3], "glfs-client-3.log"); + fs3 = new_client_create(argv[1], argv[2], logfile); + if (!fs3) + LOG_ERR("client-3 creation", EINVAL); + + fd = glfs_creat(fs1, fname, O_RDWR, 0644); + if (!fd) + LOG_ERR("glfs_creat", errno); + + test_count = 0; + + run_test_1(1); + run_test_2(2); + run_test_3(3); + run_test_4(4); + run_test_5(5); + run_test_6(6); + run_test_7(7); + run_test_8(8); + + cleanup_and_exit(0); + + return 0; +} |
