diff options
Diffstat (limited to 'tests/basic/gfapi')
37 files changed, 5857 insertions, 1514 deletions
diff --git a/tests/basic/gfapi/Makefile b/tests/basic/gfapi/Makefile index e30fefea5b9..1c5cf03ca3d 100644 --- a/tests/basic/gfapi/Makefile +++ b/tests/basic/gfapi/Makefile @@ -5,7 +5,8 @@ CFLAGS = -Wall -g $(shell pkg-config --cflags glusterfs-api) LDFLAGS = $(shell pkg-config --libs glusterfs-api) BINARIES = upcall-cache-invalidate libgfapi-fini-hang anonymous_fd seek \ - bug1283983 bug1291259 gfapi-ssl-test gfapi-load-volfile + bug1283983 bug1291259 gfapi-ssl-test gfapi-load-volfile \ + mandatory-lock-optimal %: %.c $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ diff --git a/tests/basic/gfapi/anonymous_fd_read_write.c b/tests/basic/gfapi/anonymous_fd_read_write.c index 6945dd634f0..fc276ca4310 100644 --- a/tests/basic/gfapi/anonymous_fd_read_write.c +++ b/tests/basic/gfapi/anonymous_fd_read_write.c @@ -9,95 +9,98 @@ #include <glusterfs/api/glfs.h> #include <glusterfs/api/glfs-handles.h> -#define LOG_ERR(func, ret) do { \ - if (ret != 0) { \ - fprintf (stderr, "%s : returned error %d (%s)\n", \ - func, ret, strerror (errno)); \ - goto out; \ - } else { \ - fprintf (stderr, "%s : returned %d\n", func, ret); \ - } \ - } while (0) +#define LOG_ERR(func, ret) \ + do { \ + if (ret != 0) { \ + fprintf(stderr, "%s : returned error %d (%s)\n", func, ret, \ + strerror(errno)); \ + goto out; \ + } else { \ + fprintf(stderr, "%s : returned %d\n", func, ret); \ + } \ + } while (0) int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { - int ret = 0; - glfs_t *fs = NULL; - struct glfs_object *root = NULL, *file_obj = NULL; - struct stat sb = {0, }; - char readbuf[32], writebuf[32]; - char *filename = "file.txt"; - char *logfile = NULL; - char *volname = NULL; - char *hostname = NULL; - - if (argc != 4) { - fprintf (stderr, "Invalid argument\n"); - exit(1); - } - - hostname = argv[1]; - volname = argv[2]; - logfile = argv[3]; - - fs = glfs_new (volname); - if (!fs) { - fprintf (stderr, "glfs_new: returned NULL\n"); - ret = -1; - } - - ret = glfs_set_volfile_server (fs, "tcp", hostname, 24007); - LOG_ERR("glfs_set_volfile_server", ret); - - ret = glfs_set_logging (fs, logfile, 7); - LOG_ERR("glfs_set_logging", ret); - - ret = glfs_init (fs); - LOG_ERR("glfs_init", ret); - - root = glfs_h_lookupat (fs, NULL, "/", &sb, 0); - if (root == NULL) { - fprintf (stderr, "glfs_h_lookupat: error on lookup of / ,%s\n", - strerror (errno)); - goto out; - } - - file_obj = glfs_h_creat (fs, root, filename, O_CREAT, 0644, &sb); - if (file_obj == NULL) { - fprintf (stderr, "glfs_h_creat: error on create of %s: from (%p),%s\n", - filename, root, strerror (errno)); - goto out; - } - - /* test read/write based on anonymous fd */ - memcpy (writebuf, "abcdefghijklmnopqrstuvwxyz012345", 32); - - ret = glfs_h_anonymous_write (fs, file_obj, writebuf, 32, 0); - if (ret < 0) - LOG_ERR ("glfs_h_anonymous_write", ret); - - ret = glfs_h_anonymous_read (fs, file_obj, readbuf, 32, 0); - if (ret < 0) - LOG_ERR ("glfs_h_anonymous_read", ret); - - if (memcmp (readbuf, writebuf, 32)) { - fprintf (stderr, "Failed to read what I wrote: %s %s\n", readbuf, - writebuf); - ret = -1; - goto out; - } - - ret = 0; + int ret = 0; + glfs_t *fs = NULL; + struct glfs_object *root = NULL, *file_obj = NULL; + struct stat sb = { + 0, + }; + char readbuf[32], writebuf[32]; + char *filename = "file.txt"; + char *logfile = NULL; + char *volname = NULL; + char *hostname = NULL; + + if (argc != 4) { + fprintf(stderr, "Invalid argument\n"); + exit(1); + } + + hostname = argv[1]; + volname = argv[2]; + logfile = argv[3]; + + fs = glfs_new(volname); + if (!fs) { + fprintf(stderr, "glfs_new: returned NULL\n"); + ret = -1; + } + + ret = glfs_set_volfile_server(fs, "tcp", hostname, 24007); + LOG_ERR("glfs_set_volfile_server", ret); + + ret = glfs_set_logging(fs, logfile, 7); + LOG_ERR("glfs_set_logging", ret); + + ret = glfs_init(fs); + LOG_ERR("glfs_init", ret); + + root = glfs_h_lookupat(fs, NULL, "/", &sb, 0); + if (root == NULL) { + fprintf(stderr, "glfs_h_lookupat: error on lookup of / ,%s\n", + strerror(errno)); + goto out; + } + + file_obj = glfs_h_creat(fs, root, filename, O_CREAT, 0644, &sb); + if (file_obj == NULL) { + fprintf(stderr, "glfs_h_creat: error on create of %s: from (%p),%s\n", + filename, root, strerror(errno)); + goto out; + } + + /* test read/write based on anonymous fd */ + memcpy(writebuf, "abcdefghijklmnopqrstuvwxyz012345", 32); + + ret = glfs_h_anonymous_write(fs, file_obj, writebuf, 32, 0); + if (ret < 0) + LOG_ERR("glfs_h_anonymous_write", ret); + + ret = glfs_h_anonymous_read(fs, file_obj, readbuf, 32, 0); + if (ret < 0) + LOG_ERR("glfs_h_anonymous_read", ret); + + if (memcmp(readbuf, writebuf, 32)) { + fprintf(stderr, "Failed to read what I wrote: %s %s\n", readbuf, + writebuf); + ret = -1; + goto out; + } + + ret = 0; out: - if (file_obj) - glfs_h_close (file_obj); - - if (fs) { - ret = glfs_fini(fs); - fprintf (stderr, "glfs_fini(fs) returned %d \n", ret); - } - if (ret) - exit(1); - exit(0); + if (file_obj) + glfs_h_close(file_obj); + + if (fs) { + ret = glfs_fini(fs); + fprintf(stderr, "glfs_fini(fs) returned %d \n", ret); + } + if (ret) + exit(1); + exit(0); } diff --git a/tests/basic/gfapi/bug-1241104.c b/tests/basic/gfapi/bug-1241104.c index 311323f672a..78c87595a71 100644 --- a/tests/basic/gfapi/bug-1241104.c +++ b/tests/basic/gfapi/bug-1241104.c @@ -12,81 +12,82 @@ int gfapi = 1; -#define LOG_ERR(func, ret) do { \ - if (ret != 0) { \ - fprintf (stderr, "%s : returned error %d (%s)\n", \ - func, ret, strerror (errno)); \ - goto out; \ - } else { \ - fprintf (stderr, "%s : returned %d\n", func, ret); \ - } \ - } while (0) +#define LOG_ERR(func, ret) \ + do { \ + if (ret != 0) { \ + fprintf(stderr, "%s : returned error %d (%s)\n", func, ret, \ + strerror(errno)); \ + goto out; \ + } else { \ + fprintf(stderr, "%s : returned %d\n", func, ret); \ + } \ + } while (0) int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { - glfs_t *fs = NULL; - int ret = 0, i, status = 0; - glfs_fd_t *fd = NULL; - char *filename = "file_tmp"; - char *volname = NULL; - char *logfile = NULL; - char *hostname = NULL; - struct flock lock = {0, }; - - if (argc != 4) { - fprintf (stderr, "Invalid argument\n"); - exit(1); - } - - hostname = argv[1]; - volname = argv[2]; - logfile = argv[3]; - - fs = glfs_new (volname); - if (!fs) { - fprintf (stderr, "glfs_new: returned NULL\n"); - return -1; - } - - ret = glfs_set_volfile_server (fs, "tcp", hostname, 24007); - LOG_ERR("glfs_set_volfile_server", ret); - - ret = glfs_set_logging (fs, logfile, 7); - LOG_ERR("glfs_set_logging", ret); - - ret = glfs_init (fs); - LOG_ERR("glfs_init", ret); - - fd = glfs_creat(fs, filename, O_RDWR|O_SYNC, 0644); - if (fd <= 0) { - ret = -1; - LOG_ERR ("glfs_creat", ret); - } - fprintf (stderr, "glfs-create fd - %d\n", fd); - - /* validate locks for negative range */ - lock.l_type = F_WRLCK; - lock.l_whence = SEEK_SET; - lock.l_start = 10; - lock.l_len = -9; - - ret = glfs_posix_lock (fd, F_SETLK, &lock); - LOG_ERR ("glfs_posix_lock", ret); + glfs_t *fs = NULL; + int ret = 0, i, status = 0; + glfs_fd_t *fd = NULL; + char *filename = "file_tmp"; + char *volname = NULL; + char *logfile = NULL; + char *hostname = NULL; + struct flock lock = { + 0, + }; + + if (argc != 4) { + fprintf(stderr, "Invalid argument\n"); + exit(1); + } + + hostname = argv[1]; + volname = argv[2]; + logfile = argv[3]; + + fs = glfs_new(volname); + if (!fs) { + fprintf(stderr, "glfs_new: returned NULL\n"); + return -1; + } + + ret = glfs_set_volfile_server(fs, "tcp", hostname, 24007); + LOG_ERR("glfs_set_volfile_server", ret); + + ret = glfs_set_logging(fs, logfile, 7); + LOG_ERR("glfs_set_logging", ret); + + ret = glfs_init(fs); + LOG_ERR("glfs_init", ret); + + fd = glfs_creat(fs, filename, O_RDWR | O_SYNC, 0644); + if (fd <= 0) { + ret = -1; + LOG_ERR("glfs_creat", ret); + } + fprintf(stderr, "glfs-create fd - %d\n", fd); + + /* validate locks for negative range */ + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 10; + lock.l_len = -9; + + ret = glfs_posix_lock(fd, F_SETLK, &lock); + LOG_ERR("glfs_posix_lock", ret); err: - glfs_close(fd); - LOG_ERR ("glfs_close", ret); + glfs_close(fd); + LOG_ERR("glfs_close", ret); out: - if (fs) { - ret = glfs_fini(fs); - fprintf (stderr, "glfs_fini(fs) returned %d \n", ret); - } - - if (ret) - exit(1); - exit(0); + if (fs) { + ret = glfs_fini(fs); + fprintf(stderr, "glfs_fini(fs) returned %d \n", ret); + } + + if (ret) + exit(1); + exit(0); } - - diff --git a/tests/basic/gfapi/bug-1507896.c b/tests/basic/gfapi/bug-1507896.c new file mode 100644 index 00000000000..1cc20849c2b --- /dev/null +++ b/tests/basic/gfapi/bug-1507896.c @@ -0,0 +1,49 @@ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <glusterfs/api/glfs.h> +#include <glusterfs/api/glfs-handles.h> + +#define VALIDATE_AND_GOTO_LABEL_ON_ERROR(func, ret, label) \ + do { \ + if (ret < 0) { \ + fprintf(stderr, "%s : returned error %d (%s)\n", func, ret, \ + strerror(errno)); \ + goto label; \ + } \ + } while (0) + +int +main(int argc, char *argv[]) +{ + int ret = -1; + glfs_t *fs = NULL; + char *volname = NULL; + char *logfile = NULL; + char *hostname = NULL; + + hostname = argv[1]; + volname = argv[2]; + logfile = argv[3]; + + fs = glfs_new(volname); + if (!fs) + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_new(fs)", ret, out); + + ret = glfs_set_volfile_server(fs, "tcp", hostname, 24007); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_set_volfile_server(fs)", ret, out); + + ret = glfs_set_logging(fs, logfile, 7); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_set_logging(fs)", ret, out); + + ret = glfs_init(fs); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_init(fs)", ret, out); + +out: + if (fs) { + ret = glfs_fini(fs); + if (ret) + fprintf(stderr, "glfs_fini(fs) returned %d\n", ret); + } + return ret; +} diff --git a/tests/basic/gfapi/bug-1507896.t b/tests/basic/gfapi/bug-1507896.t new file mode 100644 index 00000000000..4764e650232 --- /dev/null +++ b/tests/basic/gfapi/bug-1507896.t @@ -0,0 +1,33 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup; + +TEST glusterd + +TEST $CLI volume create $V0 $H0:$B0/brick1; +EXPECT 'Created' volinfo_field $V0 'Status'; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +logdir=`gluster --print-logdir` + +TEST build_tester $(dirname $0)/bug-1507896.c -lgfapi + +TEST ./$(dirname $0)/bug-1507896 $H0 $V0 $logdir/bug-1507896.log + +#volume name precedding with '/' +TEST ! ./$(dirname $0)/bug-1507896 $H0 /$V0 $logdir/bug-1507896.log + +#volume name passed with any special characters +TEST ! ./$(dirname $0)/bug-1507896 $H0 test@_$V0 $logdir/bug-1507896.log + +cleanup_tester $(dirname $0)/bug-1507896 + +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 + +cleanup; diff --git a/tests/basic/gfapi/bug1283983.c b/tests/basic/gfapi/bug1283983.c index 3334b290d9e..b920013d0e0 100644 --- a/tests/basic/gfapi/bug1283983.c +++ b/tests/basic/gfapi/bug1283983.c @@ -10,114 +10,113 @@ #include <glusterfs/api/glfs-handles.h> int gfapi = 1; -#define LOG_ERR(func, ret) do { \ - if (ret != 0) { \ - fprintf (stderr, "%s : returned error ret(%d), errno(%d)\n", \ - func, ret, errno); \ - exit(1); \ - } else { \ - fprintf (stderr, "%s : returned %d\n", func, ret); \ - } \ - } while (0) -#define LOG_IF_NO_ERR(func, ret) do { \ - if (ret == 0) { \ - fprintf (stderr, "%s : hasn't returned error %d\n", \ - func, ret); \ - exit(1); \ - } else { \ - fprintf (stderr, "%s : returned %d\n", func, ret); \ - } \ - } while (0) +#define LOG_ERR(func, ret) \ + do { \ + if (ret != 0) { \ + fprintf(stderr, "%s : returned error ret(%d), errno(%d)\n", func, \ + ret, errno); \ + exit(1); \ + } else { \ + fprintf(stderr, "%s : returned %d\n", func, ret); \ + } \ + } while (0) +#define LOG_IF_NO_ERR(func, ret) \ + do { \ + if (ret == 0) { \ + fprintf(stderr, "%s : hasn't returned error %d\n", func, ret); \ + exit(1); \ + } else { \ + fprintf(stderr, "%s : returned %d\n", func, ret); \ + } \ + } while (0) int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { - glfs_t *fs = NULL; - int ret = 0, i; - glfs_fd_t *fd = NULL; - char *filename = "/a1"; - char *filename2 = "/a2"; - struct stat sb = {0, }; - struct glfs_upcall *cbk = NULL; - char *logfile = NULL; - char *volname = NULL; - int cnt = 1; - struct glfs_upcall_inode *in_arg = NULL; - struct glfs_object *root = NULL, *leaf = NULL; - - fprintf (stderr, "Starting libgfapi_fini\n"); - if (argc != 4) { - fprintf (stderr, "Invalid argument\n"); - exit(1); + glfs_t *fs = NULL; + int ret = 0, i; + glfs_fd_t *fd = NULL; + char *filename = "/a1"; + char *filename2 = "/a2"; + struct stat sb = { + 0, + }; + struct glfs_upcall *cbk = NULL; + char *logfile = NULL; + char *volname = NULL; + int cnt = 1; + struct glfs_upcall_inode *in_arg = NULL; + struct glfs_object *root = NULL, *leaf = NULL; + + fprintf(stderr, "Starting libgfapi_fini\n"); + if (argc != 4) { + fprintf(stderr, "Invalid argument\n"); + exit(1); + } + + hostname = argv[1] volname = argv[2]; + logfile = argv[3]; + + fs = glfs_new(volname); + if (!fs) { + fprintf(stderr, "glfs_new: returned NULL\n"); + return 1; + } + + ret = glfs_set_volfile_server(fs, "tcp", hostname, 24007); + LOG_ERR("glfs_set_volfile_server", ret); + + ret = glfs_set_logging(fs, logfile, 7); + LOG_ERR("glfs_set_logging", ret); + + ret = glfs_init(fs); + LOG_ERR("glfs_init", ret); + + sleep(2); + root = glfs_h_lookupat(fs, NULL, "/", &sb, 0); + if (!root) { + ret = -1; + LOG_ERR("glfs_h_lookupat root", ret); + } + leaf = glfs_h_lookupat(fs, root, filename, &sb, 0); + if (!leaf) { + ret = -1; + LOG_IF_NO_ERR("glfs_h_lookupat leaf", ret); + } + + leaf = glfs_h_creat(fs, root, filename, O_RDWR, 0644, &sb); + if (!leaf) { + ret = -1; + LOG_ERR("glfs_h_lookupat leaf", ret); + } + fprintf(stderr, "glfs_h_create leaf - %p\n", leaf); + + leaf = glfs_h_lookupat(fs, root, filename2, &sb, 0); + if (!leaf) { + ret = -1; + LOG_IF_NO_ERR("glfs_h_lookupat leaf", ret); + } + + ret = glfs_h_rename(fs, root, filename, root, filename2); + LOG_ERR("glfs_rename", ret); + + while (cnt++ < 5) { + ret = glfs_h_poll_upcall(fs, &cbk); + LOG_ERR("glfs_h_poll_upcall", ret); + + /* There should not be any upcalls sent */ + if (glfs_upcall_get_reason(cbk) != GLFS_UPCALL_EVENT_NULL) { + fprintf(stderr, "Error: Upcall received(%d)\n", + glfs_upcall_get_reason(cbk)); + exit(1); } - hostname = argv[1] - volname = argv[2]; - logfile = argv[3]; + glfs_free(cbk); + } + ret = glfs_fini(fs); + LOG_ERR("glfs_fini", ret); - fs = glfs_new (volname); - if (!fs) { - fprintf (stderr, "glfs_new: returned NULL\n"); - return 1; - } - - ret = glfs_set_volfile_server (fs, "tcp", hostname, 24007); - LOG_ERR("glfs_set_volfile_server", ret); - - ret = glfs_set_logging (fs, logfile, 7); - LOG_ERR("glfs_set_logging", ret); - - ret = glfs_init (fs); - LOG_ERR("glfs_init", ret); - - sleep (2); - root = glfs_h_lookupat (fs, NULL, "/", &sb, 0); - if (!root) { - ret = -1; - LOG_ERR ("glfs_h_lookupat root", ret); - } - leaf = glfs_h_lookupat (fs, root, filename, &sb, 0); - if (!leaf) { - ret = -1; - LOG_IF_NO_ERR ("glfs_h_lookupat leaf", ret); - } - - leaf = glfs_h_creat (fs, root, filename, O_RDWR, 0644, &sb); - if (!leaf) { - ret = -1; - LOG_ERR ("glfs_h_lookupat leaf", ret); - } - fprintf (stderr, "glfs_h_create leaf - %p\n", leaf); - - leaf = glfs_h_lookupat (fs, root, filename2, &sb, 0); - if (!leaf) { - ret = -1; - LOG_IF_NO_ERR ("glfs_h_lookupat leaf", ret); - } - - ret = glfs_h_rename (fs, root, filename, root, filename2); - LOG_ERR("glfs_rename", ret); - - while (cnt++ < 5) { - ret = glfs_h_poll_upcall(fs, &cbk); - LOG_ERR ("glfs_h_poll_upcall", ret); - - /* There should not be any upcalls sent */ - if (glfs_upcall_get_reason(cbk) != GLFS_UPCALL_EVENT_NULL) { - fprintf (stderr, "Error: Upcall received(%d)\n", - glfs_upcall_get_reason(cbk)); - exit (1); - } - - glfs_free (cbk); - } - - ret = glfs_fini(fs); - LOG_ERR("glfs_fini", ret); - - fprintf (stderr, "End of libgfapi_fini\n"); + fprintf(stderr, "End of libgfapi_fini\n"); - exit(0); + exit(0); } - - diff --git a/tests/basic/gfapi/bug1291259.c b/tests/basic/gfapi/bug1291259.c index 26fc1e01449..cd7bc65268b 100644 --- a/tests/basic/gfapi/bug1291259.c +++ b/tests/basic/gfapi/bug1291259.c @@ -10,174 +10,172 @@ #include <glusterfs/api/glfs-handles.h> int gfapi = 1; -#define LOG_ERR(func, ret) do { \ - if (ret != 0) { \ - fprintf (stderr, "%s : returned error ret(%d), errno(%d)\n", \ - func, ret, errno); \ - exit(1); \ - } else { \ - fprintf (stderr, "%s : returned %d\n", func, ret); \ - } \ - } while (0) -#define LOG_IF_NO_ERR(func, ret) do { \ - if (ret == 0) { \ - fprintf (stderr, "%s : hasn't returned error %d\n", \ - func, ret); \ - exit(1); \ - } else { \ - fprintf (stderr, "%s : returned %d\n", func, ret); \ - } \ - } while (0) +#define LOG_ERR(func, ret) \ + do { \ + if (ret != 0) { \ + fprintf(stderr, "%s : returned error ret(%d), errno(%d)\n", func, \ + ret, errno); \ + exit(1); \ + } else { \ + fprintf(stderr, "%s : returned %d\n", func, ret); \ + } \ + } while (0) +#define LOG_IF_NO_ERR(func, ret) \ + do { \ + if (ret == 0) { \ + fprintf(stderr, "%s : hasn't returned error %d\n", func, ret); \ + exit(1); \ + } else { \ + fprintf(stderr, "%s : returned %d\n", func, ret); \ + } \ + } while (0) #define GLAPI_UUID_LENGTH 16 int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { - glfs_t *fs = NULL; - glfs_t *fs2 = NULL; - int ret = 0, i; - glfs_fd_t *fd = NULL; - char *filename = "/a1"; - char *filename2 = "/a2"; - struct stat sb = {0, }; - char *logfile = NULL; - char *volname = NULL; - char *hostname = NULL; - int cnt = 1; - int upcall_received = 0; - struct glfs_upcall *cbk = NULL; - struct glfs_object *root = NULL, *leaf = NULL; - unsigned char globjhdl[GFAPI_HANDLE_LENGTH]; - unsigned char globjhdl2[GFAPI_HANDLE_LENGTH]; - - fprintf (stderr, "Starting libgfapi_fini\n"); - if (argc != 4) { - fprintf (stderr, "Invalid argument\n"); - exit(1); - } + glfs_t *fs = NULL; + glfs_t *fs2 = NULL; + int ret = 0, i; + glfs_fd_t *fd = NULL; + char *filename = "/a1"; + char *filename2 = "/a2"; + struct stat sb = { + 0, + }; + char *logfile = NULL; + char *volname = NULL; + char *hostname = NULL; + int cnt = 1; + int upcall_received = 0; + struct glfs_upcall *cbk = NULL; + struct glfs_object *root = NULL, *leaf = NULL; + unsigned char globjhdl[GFAPI_HANDLE_LENGTH]; + unsigned char globjhdl2[GFAPI_HANDLE_LENGTH]; + + fprintf(stderr, "Starting libgfapi_fini\n"); + if (argc != 4) { + fprintf(stderr, "Invalid argument\n"); + exit(1); + } + + hostname = argv[1]; + volname = argv[2]; + logfile = argv[3]; + + fs = glfs_new(volname); + if (!fs) { + fprintf(stderr, "glfs_new: returned NULL\n"); + return 1; + } + + ret = glfs_set_volfile_server(fs, "tcp", hostname, 24007); + LOG_ERR("glfs_set_volfile_server", ret); + + ret = glfs_set_logging(fs, logfile, 7); + LOG_ERR("glfs_set_logging", ret); + + ret = glfs_init(fs); + LOG_ERR("glfs_init", ret); + + /* This does not block, but enables caching of events. Real + * applications like NFS-Ganesha run this in a thread before activity + * on the fs (through this instance) happens. */ + ret = glfs_h_poll_upcall(fs, &cbk); + LOG_ERR("glfs_h_poll_upcall", ret); + + fs2 = glfs_new(volname); + if (!fs) { + fprintf(stderr, "glfs_new: returned NULL\n"); + return 1; + } + + ret = glfs_set_volfile_server(fs2, "tcp", hostname, 24007); + LOG_ERR("glfs_set_volfile_server", ret); + + ret = glfs_set_logging(fs2, logfile, 7); + LOG_ERR("glfs_set_logging", ret); + + ret = glfs_init(fs2); + LOG_ERR("glfs_init", ret); + + sleep(2); + root = glfs_h_lookupat(fs, NULL, "/", &sb, 0); + if (!root) { + ret = -1; + LOG_ERR("glfs_h_lookupat root", ret); + } + leaf = glfs_h_lookupat(fs, root, filename, &sb, 0); + if (!leaf) { + ret = -1; + LOG_IF_NO_ERR("glfs_h_lookupat leaf", ret); + } + + root = glfs_h_lookupat(fs2, NULL, "/", &sb, 0); + if (!root) { + ret = -1; + LOG_ERR("glfs_h_lookupat root", ret); + } + leaf = glfs_h_creat(fs2, root, filename, O_RDWR, 0644, &sb); + if (!leaf) { + ret = -1; + LOG_ERR("glfs_h_lookupat leaf", ret); + } + fprintf(stderr, "glfs_h_create leaf - %p\n", leaf); + + while (cnt++ < 5 && !upcall_received) { + enum glfs_upcall_reason reason = 0; + struct glfs_upcall_inode *in_arg = NULL; - hostname = argv[1]; - volname = argv[2]; - logfile = argv[3]; + ret = glfs_h_poll_upcall(fs, &cbk); + LOG_ERR("glfs_h_poll_upcall", ret); + if (ret) + goto retry; + reason = glfs_upcall_get_reason(cbk); + fprintf(stderr, "Upcall received(%d)\n", reason); - fs = glfs_new (volname); - if (!fs) { - fprintf (stderr, "glfs_new: returned NULL\n"); - return 1; - } + if (reason == GLFS_UPCALL_INODE_INVALIDATE) { + struct glfs_object *object = NULL; - ret = glfs_set_volfile_server (fs, "tcp", hostname, 24007); - LOG_ERR("glfs_set_volfile_server", ret); + in_arg = glfs_upcall_get_event(cbk); + object = glfs_upcall_inode_get_object(in_arg); - ret = glfs_set_logging (fs, logfile, 7); - LOG_ERR("glfs_set_logging", ret); + ret = glfs_h_extract_handle(root, globjhdl + GLAPI_UUID_LENGTH, + GFAPI_HANDLE_LENGTH); + LOG_ERR("glfs_h_extract_handle", (ret != 16)); - ret = glfs_init (fs); - LOG_ERR("glfs_init", ret); + ret = glfs_h_extract_handle(object, globjhdl2 + GLAPI_UUID_LENGTH, + GFAPI_HANDLE_LENGTH); + LOG_ERR("glfs_h_extract_handle", (ret != 16)); - /* This does not block, but enables caching of events. Real - * applications like NFS-Ganesha run this in a thread before activity - * on the fs (through this instance) happens. */ - ret = glfs_h_poll_upcall(fs, &cbk); - LOG_ERR ("glfs_h_poll_upcall", ret); - - fs2 = glfs_new (volname); - if (!fs) { - fprintf (stderr, "glfs_new: returned NULL\n"); - return 1; + if (memcmp(globjhdl + GLAPI_UUID_LENGTH, + globjhdl2 + GLAPI_UUID_LENGTH, 16)) { + fprintf(stderr, "Error: gfid mismatch\n"); + exit(1); + } + upcall_received = 1; } - ret = glfs_set_volfile_server (fs2, "tcp", hostname, 24007); - LOG_ERR("glfs_set_volfile_server", ret); - - ret = glfs_set_logging (fs2, logfile, 7); - LOG_ERR("glfs_set_logging", ret); - - ret = glfs_init (fs2); - LOG_ERR("glfs_init", ret); + retry: + if (!upcall_received) + sleep(1); /* glfs_h_poll_upcall() does not block */ - sleep (2); - root = glfs_h_lookupat (fs, NULL, "/", &sb, 0); - if (!root) { - ret = -1; - LOG_ERR ("glfs_h_lookupat root", ret); - } - leaf = glfs_h_lookupat (fs, root, filename, &sb, 0); - if (!leaf) { - ret = -1; - LOG_IF_NO_ERR ("glfs_h_lookupat leaf", ret); - } - - root = glfs_h_lookupat (fs2, NULL, "/", &sb, 0); - if (!root) { - ret = -1; - LOG_ERR ("glfs_h_lookupat root", ret); - } - leaf = glfs_h_creat (fs2, root, filename, O_RDWR, 0644, &sb); - if (!leaf) { - ret = -1; - LOG_ERR ("glfs_h_lookupat leaf", ret); - } - fprintf (stderr, "glfs_h_create leaf - %p\n", leaf); - - while (cnt++ < 5 && !upcall_received) { - enum glfs_upcall_reason reason = 0; - struct glfs_upcall_inode *in_arg = NULL; - - ret = glfs_h_poll_upcall(fs, &cbk); - LOG_ERR ("glfs_h_poll_upcall", ret); - if (ret) - goto retry; - - reason = glfs_upcall_get_reason (cbk); - fprintf (stderr, "Upcall received(%d)\n", reason); - - if (reason == GLFS_UPCALL_INODE_INVALIDATE) { - struct glfs_object *object = NULL; - - in_arg = glfs_upcall_get_event (cbk); - object = glfs_upcall_inode_get_object (in_arg); - - ret = glfs_h_extract_handle (root, - globjhdl+GLAPI_UUID_LENGTH, - GFAPI_HANDLE_LENGTH); - LOG_ERR("glfs_h_extract_handle", (ret != 16)); - - ret = glfs_h_extract_handle (object, - globjhdl2+GLAPI_UUID_LENGTH, - GFAPI_HANDLE_LENGTH); - LOG_ERR("glfs_h_extract_handle", (ret != 16)); - - if (memcmp (globjhdl+GLAPI_UUID_LENGTH, - globjhdl2+GLAPI_UUID_LENGTH, 16)) { - fprintf (stderr, "Error: gfid mismatch\n"); - exit (1); - } - upcall_received = 1; - } - -retry: - if (!upcall_received) - sleep (1); /* glfs_h_poll_upcall() does not block */ - - if (!ret) { - glfs_free (cbk); - cbk = NULL; - } + if (!ret) { + glfs_free(cbk); + cbk = NULL; } + } - if (!upcall_received) { - fprintf (stderr, "Error: Upcall not received\n"); - exit (1); - } + if (!upcall_received) { + fprintf(stderr, "Error: Upcall not received\n"); + exit(1); + } - ret = glfs_fini(fs); - LOG_ERR("glfs_fini", ret); + ret = glfs_fini(fs); + LOG_ERR("glfs_fini", ret); - fprintf (stderr, "End of libgfapi_fini\n"); + fprintf(stderr, "End of libgfapi_fini\n"); - exit(0); + exit(0); } - - diff --git a/tests/basic/gfapi/bug1613098.c b/tests/basic/gfapi/bug1613098.c new file mode 100644 index 00000000000..ee67e97a034 --- /dev/null +++ b/tests/basic/gfapi/bug1613098.c @@ -0,0 +1,96 @@ +#include <inttypes.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#include <glusterfs/api/glfs.h> +#include <glusterfs/api/glfs-handles.h> + +#define ACL_TYPE_ACCESS (0x8000) + +#define VALIDATE_AND_GOTO_LABEL_ON_ERROR(func, ret, label) \ + do { \ + if (ret < 0) { \ + fprintf(stderr, "%s : returned error %d (%s)\n", func, ret, \ + strerror(errno)); \ + goto label; \ + } \ + } while (0) + +int +main(int argc, char *argv[]) +{ + int ret = -1; + int flags = O_RDWR | O_SYNC; + glfs_t *fs = NULL; + glfs_fd_t *fd = NULL; + char *volname = NULL; + char *logfile = NULL; + const char *filename = "file_tmp"; + struct glfs_object *object = NULL; + acl_t acl = NULL; + struct stat sb; + + if (argc != 3) { + fprintf(stderr, "Invalid argument\n"); + return 1; + } + + volname = argv[1]; + logfile = argv[2]; + + fs = glfs_new(volname); + if (!fs) + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_new", ret, out); + + ret = glfs_set_volfile_server(fs, "tcp", "localhost", 24007); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_set_volfile_server", ret, out); + + ret = glfs_set_logging(fs, logfile, 7); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_set_logging", ret, out); + + ret = glfs_init(fs); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_init", ret, out); + + fd = glfs_creat(fs, filename, flags, 0044); + if (fd == NULL) { + ret = -1; + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_creat", ret, out); + } + glfs_close(fd); + + object = glfs_h_lookupat(fs, NULL, filename, NULL, 0); + if (object == NULL) { + ret = -1; + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_h_lookupat", ret, out); + } + + ret = glfs_chown(fs, filename, 99, 99); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_chown", ret, out); + + ret = glfs_setfsuid(99); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_setfsuid", ret, out); + + ret = glfs_setfsgid(99); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_setfsgid", ret, out); + + acl = glfs_h_acl_get(fs, object, ACL_TYPE_ACCESS); + if (acl == NULL) { + ret = -1; + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_h_acl_get", ret, out); + } + + ret = glfs_h_acl_set(fs, object, ACL_TYPE_ACCESS, acl); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_h_acl_get", ret, out); +out: + glfs_setfsuid(0); + glfs_setfsgid(0); + + if (object) + glfs_h_close(object); + + if (fs) + glfs_fini(fs); + + return ret; +} diff --git a/tests/basic/gfapi/bug1613098.t b/tests/basic/gfapi/bug1613098.t new file mode 100755 index 00000000000..e4acc2b76bf --- /dev/null +++ b/tests/basic/gfapi/bug1613098.t @@ -0,0 +1,22 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +TEST glusterd + +TEST $CLI volume create $V0 ${H0}:$B0/brick1; +EXPECT 'Created' volinfo_field $V0 'Status'; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +logdir=`gluster --print-logdir` + +build_tester $(dirname $0)/bug1613098.c -lgfapi + +TEST ./$(dirname $0)/bug1613098 $V0 $logdir/bug1613098.log + +cleanup_tester $(dirname $0)/bug1613098 + +cleanup; diff --git a/tests/basic/gfapi/gfapi-async-calls-test.c b/tests/basic/gfapi/gfapi-async-calls-test.c index 277067bee2c..55835b14709 100644 --- a/tests/basic/gfapi/gfapi-async-calls-test.c +++ b/tests/basic/gfapi/gfapi-async-calls-test.c @@ -9,169 +9,486 @@ #include <glusterfs/api/glfs.h> #include <glusterfs/api/glfs-handles.h> -#define LOG_ERR(msg) do { \ - fprintf (stderr, "%s : Error (%s)\n", msg, strerror (errno)); \ - } while (0) +#define LOG_ERR(msg) \ + do { \ + fprintf(stderr, "%s : Error (%s)\n", msg, strerror(errno)); \ + } while (0) int cbk_complete = 0; int cbk_ret_val = -1; -int -fill_iov (struct iovec *iov, char fillchar, int count) +void +cbk_check() { - int ret = -1; + while (cbk_complete != 1) { + sleep(1); + } + if (cbk_ret_val < 0) { + fprintf(stderr, "cbk_ret_val is -ve\n"); + } +} - iov->iov_base = calloc (count + 1, sizeof(fillchar)); - if (iov->iov_base == NULL) { - return ret; - } else { - iov->iov_len = count; - ret = 0; - } - memset (iov->iov_base, fillchar, count); - memset (iov->iov_base + count, '\0', 1); +int +fill_iov(struct iovec *iov, char fillchar, int count) +{ + int ret = -1; + iov->iov_base = malloc(count + 1); + if (iov->iov_base == NULL) { return ret; + } else { + iov->iov_len = count; + ret = 0; + } + memset(iov->iov_base, fillchar, count); + memset(iov->iov_base + count, '\0', 1); + + return ret; } glfs_t * -init_glfs (const char *hostname, const char *volname, - const char *logfile) -{ - int ret = -1; - glfs_t *fs = NULL; - - fs = glfs_new (volname); - if (!fs) { - LOG_ERR ("glfs_new failed"); - return NULL; - } - - ret = glfs_set_volfile_server (fs, "tcp", hostname, 24007); - if (ret < 0) { - LOG_ERR ("glfs_set_volfile_server failed"); - goto out; - } - - ret = glfs_set_logging (fs, logfile, 7); - if (ret < 0) { - LOG_ERR ("glfs_set_logging failed"); - goto out; - } - - ret = glfs_init (fs); - if (ret < 0) { - LOG_ERR ("glfs_init failed"); - goto out; - } +init_glfs(const char *hostname, const char *volname, const char *logfile) +{ + int ret = -1; + glfs_t *fs = NULL; + + fs = glfs_new(volname); + if (!fs) { + LOG_ERR("glfs_new failed"); + return NULL; + } + + ret = glfs_set_volfile_server(fs, "tcp", hostname, 24007); + if (ret < 0) { + LOG_ERR("glfs_set_volfile_server failed"); + goto out; + } + + ret = glfs_set_logging(fs, logfile, 7); + if (ret < 0) { + LOG_ERR("glfs_set_logging failed"); + goto out; + } + + ret = glfs_init(fs); + if (ret < 0) { + LOG_ERR("glfs_init failed"); + goto out; + } + + ret = 0; +out: + if (ret) { + glfs_fini(fs); + fs = NULL; + } - ret = 0; + return fs; +} + +void +pwritev_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_pwritev failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; +} + +int +pwritev_async(glfs_t *fs, glfs_fd_t *glfd, int char_count) +{ + ssize_t ret = -1; + int flags = O_RDWR; + struct iovec iov = {0}; + void *write_cookie = NULL; + + ret = fill_iov(&iov, 'a', char_count); + if (ret) { + LOG_ERR("failed to create iov"); + goto out; + } + + write_cookie = strdup("write_cookie"); + ret = glfs_pwritev_async(glfd, &iov, 1, 0, flags, pwritev_async_cbk, + &write_cookie); out: - if (ret) { - glfs_fini (fs); - fs = NULL; - } + if (ret < 0) { + LOG_ERR("glfs_pwritev async failed"); + } + return ret; +} - return fs; +void +pwrite_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_pwrite_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; +} + +int +pwrite_async(glfs_fd_t *glfd) +{ + ssize_t ret = -1; + int flags = O_RDWR; + char buf1[10]; + char *buf2 = "ten bytes!"; + void *write_cookie = strdup("write_cookie"); + ret = glfs_pwrite_async(glfd, buf1, 10, 0, flags, pwrite_async_cbk, + &write_cookie); + + if (ret < 0) { + LOG_ERR("glfs_pwrite_async failed"); + } + return ret; } void -write_async_cbk (glfs_fd_t *fd, ssize_t ret, void *cookie) +writev_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_writev_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; +} + +int +writev_async(glfs_t *fs, glfs_fd_t *glfd, int char_count) { + ssize_t ret = -1; + int flags = O_RDWR; + struct iovec iov = {0}; + void *write_cookie = NULL; + + ret = fill_iov(&iov, 'a', char_count); + if (ret) { + LOG_ERR("failed to create iov"); + goto out; + } + + write_cookie = strdup("write_cookie"); + ret = glfs_writev_async(glfd, &iov, 1, flags, writev_async_cbk, + &write_cookie); +out: + if (ret < 0) { + LOG_ERR("glfs_writev_async failed"); + } + return ret; +} - if (ret < 0) { - LOG_ERR ("glfs_write failed"); - } - cbk_ret_val = ret; - cbk_complete = 1; +void +write_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_write_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; } int -write_async (glfs_t *fs, glfs_fd_t *glfd, int char_count) +write_async(glfs_fd_t *glfd) { - ssize_t ret = -1; - int flags = O_RDWR; - const char *buff = "This is from my prog\n"; - struct iovec iov = {0}; - void *write_cookie = NULL; - void *read_cookie = NULL; + ssize_t ret = -1; + int flags = O_RDWR; + char buf1[10]; + char *buf2 = "ten bytes!"; + void *write_cookie = strdup("write_cookie"); + ret = glfs_write_async(glfd, buf1, 10, flags, write_async_cbk, + &write_cookie); + + if (ret < 0) { + LOG_ERR("glfs_write_async failed"); + } + return ret; +} +void +preadv_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_preadv_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; +} +int +preadv_async(glfs_t *fs, glfs_fd_t *glfd, int char_count) +{ + ssize_t ret = -1; + int flags = O_RDWR; + struct iovec iov = {0}; + void *read_cookie = NULL; + + ret = fill_iov(&iov, 'a', char_count); + if (ret) { + LOG_ERR("failed to create iov"); + goto out; + } + + read_cookie = strdup("preadv_cookie"); + ret = glfs_preadv_async(glfd, &iov, 1, 0, flags, preadv_async_cbk, + &read_cookie); +out: + if (ret < 0) { + LOG_ERR("glfs_preadv async failed"); + } + return ret; +} + +void +pread_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_pread_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; +} + +int +pread_async(glfs_fd_t *glfd) +{ + ssize_t ret = -1; + int flags = O_RDWR; + char buf1[10]; + void *read_cookie = strdup("read_cookie"); + ret = glfs_pread_async(glfd, buf1, 10, 0, flags, pread_async_cbk, + &read_cookie); + if (ret < 0) { + LOG_ERR("glfs_pread_async failed"); + } + + return ret; +} - ret = fill_iov (&iov, 'a', char_count); - if (ret) { - LOG_ERR ("failed to create iov"); - goto out; - } +void +readv_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_readv_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; +} - write_cookie = strdup ("write_cookie"); - ret = glfs_pwritev_async (glfd, &iov, 1, 0, flags, write_async_cbk, - &write_cookie); +int +readv_async(glfs_t *fs, glfs_fd_t *glfd, int char_count) +{ + ssize_t ret = -1; + int flags = O_RDWR; + struct iovec iov = {0}; + void *read_cookie = NULL; + + ret = fill_iov(&iov, 'a', char_count); + if (ret) { + LOG_ERR("failed to create iov"); + goto out; + } + + read_cookie = strdup("read_cookie"); + ret = glfs_readv_async(glfd, &iov, 1, flags, readv_async_cbk, &read_cookie); out: - if (ret < 0) { - LOG_ERR ("glfs_pwritev async failed"); - } - return ret; + if (ret < 0) { + LOG_ERR("glfs_readv_async failed"); + } + return ret; +} +void +read_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_read_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; } int -main (int argc, char *argv[]) -{ - int ret = 0; - char *hostname = NULL; - char *volname = NULL; - char *logfile = NULL; - glfs_t *fs = NULL; - const char *filename = "glfs_test.txt"; - int flags = (O_RDWR|O_CREAT); - glfs_fd_t *glfd = NULL; - int count = 200; - - if (argc != 4) { - fprintf (stderr, "Invalid argument\n"); - exit(1); - } - - hostname = argv[1]; - volname = argv[2]; - logfile = argv[3]; - - fs = init_glfs (hostname, volname, logfile); - if (fs == NULL) { - LOG_ERR ("init_glfs failed"); - return -1; - } - - glfd = glfs_creat (fs, filename, flags, 0644); - if (glfd == NULL) { - LOG_ERR ("glfs_creat failed"); - exit(1); - } - - ret = write_async (fs, glfd, count); - if (ret) { - LOG_ERR ("glfs_test_function failed"); - exit(1); - } - - while (cbk_complete != 1) { - sleep(1); - } - - ret = glfs_close (glfd); - if (ret < 0) { - LOG_ERR ("glfs close failed"); - } - - /* - * skipping fini - */ - - if (cbk_ret_val == count) - return 0; - else - return -1; +read_async(glfs_fd_t *glfd) +{ + ssize_t ret = -1; + int flags = O_RDWR; + char buf1[10]; + void *read_cookie = strdup("read_cookie"); + ret = glfs_read_async(glfd, buf1, 10, flags, read_async_cbk, &read_cookie); + + if (ret < 0) { + LOG_ERR("glfs_read_async failed"); + } + return ret; +} + +void +fsync_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_fsync_async_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; +} + +void +fdatasync_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_fdatasync_async_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; } +void +ftruncate_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_ftruncate_async_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; +} +int +main(int argc, char *argv[]) +{ + int ret = 0; + char *hostname = NULL; + char *volname = NULL; + char *logfile = NULL; + glfs_t *fs = NULL; + const char *filename = "glfs_test.txt"; + int flags = (O_RDWR | O_CREAT); + glfs_fd_t *glfd = NULL; + int count = 200; + void *data = strdup("Sample_text"); + + if (argc != 4) { + fprintf(stderr, "Invalid argument\n"); + exit(1); + } + + hostname = argv[1]; + volname = argv[2]; + logfile = argv[3]; + + fs = init_glfs(hostname, volname, logfile); + if (fs == NULL) { + LOG_ERR("init_glfs failed"); + return -1; + } + + glfd = glfs_creat(fs, filename, flags, 0644); + if (glfd == NULL) { + LOG_ERR("glfs_creat failed"); + exit(1); + } + + ret = pwritev_async(fs, glfd, count); + if (ret) { + LOG_ERR("glfs_pwritev_async_test failed"); + exit(1); + } + cbk_check(); + + ret = writev_async(fs, glfd, count); + if (ret) { + LOG_ERR("glfs_writev_async_test failed"); + exit(1); + } + cbk_check(); + + ret = write_async(glfd); + if (ret) { + LOG_ERR("glfs_write_async_test failed"); + exit(1); + } + cbk_check(); + + ret = preadv_async(fs, glfd, count); + if (ret) { + LOG_ERR("glfs_preadv_async_test failed"); + exit(1); + } + cbk_check(); + + ret = pread_async(glfd); + if (ret) { + LOG_ERR("glfs_pread_async_test failed"); + exit(1); + } + cbk_check(); + + ret = readv_async(fs, glfd, count); + if (ret) { + LOG_ERR("glfs_readv_async_test failed"); + exit(1); + } + cbk_check(); + + ret = read_async(glfd); + if (ret) { + LOG_ERR("glfs_read_async_test failed"); + exit(1); + } + cbk_check(); + + ret = glfs_fsync(glfd, NULL, NULL); + if (ret < 0) { + LOG_ERR("glfs_fsync failed"); + exit(1); + } + + ret = glfs_fdatasync(glfd, NULL, NULL); + if (ret < 0) { + LOG_ERR("glfs_fdatasync failed"); + exit(1); + } + + ret = glfs_fsync_async(glfd, fsync_async_cbk, data); + if (ret < 0) { + LOG_ERR("glfs_fsync_async failed"); + exit(1); + } + cbk_check(); + + ret = glfs_fdatasync_async(glfd, fdatasync_async_cbk, data); + if (ret < 0) { + LOG_ERR("glfs_fdatasync_async failed"); + exit(1); + } + cbk_check(); + + ret = glfs_ftruncate_async(glfd, 4, ftruncate_async_cbk, data); + if (ret < 0) { + LOG_ERR("glfs_ftruncate_async failed"); + exit(1); + } + + ret = glfs_close(glfd); + if (ret < 0) { + LOG_ERR("glfs close failed"); + } + + ret = glfs_fini(fs); + + return ret; +} diff --git a/tests/basic/gfapi/gfapi-copy-file-range.t b/tests/basic/gfapi/gfapi-copy-file-range.t new file mode 100644 index 00000000000..a56d3a58e07 --- /dev/null +++ b/tests/basic/gfapi/gfapi-copy-file-range.t @@ -0,0 +1,82 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup; + +mkfs.xfs 2>&1 | grep reflink +if [ $? -ne 0 ]; then + SKIP_TESTS + exit +fi + + +TEST glusterd + +TEST truncate -s 2G $B0/xfs_image +# for now, a xfs filesystem with reflink support is created. +# In future, better to make changes in MKFS_LOOP so that, +# once can create a xfs filesystem with reflink enabled in +# generic and simple way, instead of doing below steps each +# time. +TEST mkfs.xfs -f -i size=512 -m reflink=1 $B0/xfs_image; + +TEST mkdir $B0/bricks +TEST mount -t xfs -o loop $B0/xfs_image $B0/bricks + +# Just a single brick volume. More test cases need to be +# added in future for distribute, replicate, +# distributed replicate and distributed replicated sharded +# volumes. +TEST $CLI volume create $V0 $H0:$B0/bricks/brick1; +EXPECT 'Created' volinfo_field $V0 'Status'; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 + +TEST dd if=/dev/urandom of=$M0/file bs=1M count=555; + +# check for the existence of the created file +TEST stat $M0/file; + +# grab the size of the file +SRC_SIZE=$(stat -c %s $M0/file); + +logdir=`gluster --print-logdir` + +# TODO: +# For now, do not call copy-file-range utility. This is because, +# the regression machines are centos-7 based which does not have +# copy_file_range API available. So, instead of this testcase +# causing regression failures, for now, this is just a dummy test +# case. Uncomment the below tests (until volume stop) when there +# is support for copy_file_range in the regression machines. +# + +TEST build_tester $(dirname $0)/glfs-copy-file-range.c -lgfapi + +TEST ./$(dirname $0)/glfs-copy-file-range $H0 $V0 $logdir/gfapi-copy-file-range.log /file /new + +# check whether the destination file is created or not +TEST stat $M0/new + +# check the size of the destination file +DST_SIZE=$(stat -c %s $M0/new); + +# The sizes of the source and destination should be same. +# Atleast it ensures that, copy_file_range API is working +# as expected. Whether the actual cloning happened via reflink +# or a read/write happened is different matter. +TEST [ $SRC_SIZE == $DST_SIZE ]; + +cleanup_tester $(dirname $0)/glfs-copy-file-range + +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 + +UMOUNT_LOOP $B0/bricks; + +cleanup; diff --git a/tests/basic/gfapi/gfapi-dup.c b/tests/basic/gfapi/gfapi-dup.c index 96f133eae33..028108e4590 100644 --- a/tests/basic/gfapi/gfapi-dup.c +++ b/tests/basic/gfapi/gfapi-dup.c @@ -4,81 +4,81 @@ #include <glusterfs/api/glfs.h> #include <glusterfs/api/glfs-handles.h> -#define VALIDATE_AND_GOTO_LABEL_ON_ERROR(func, ret, label) do { \ - if (ret < 0) { \ - fprintf (stderr, "%s : returned error %d (%s)\n", \ - func, ret, strerror (errno)); \ - goto label; \ - } \ - } while (0) +#define VALIDATE_AND_GOTO_LABEL_ON_ERROR(func, ret, label) \ + do { \ + if (ret < 0) { \ + fprintf(stderr, "%s : returned error %d (%s)\n", func, ret, \ + strerror(errno)); \ + goto label; \ + } \ + } while (0) int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { - int ret = -1; - int flags = O_RDWR|O_SYNC; - glfs_t *fs = NULL; - glfs_fd_t *fd1 = NULL; - glfs_fd_t *fd2 = NULL; - char *volname = NULL; - char *logfile = NULL; - char *hostname = NULL; - const char *filename = "file_tmp"; - const char *buff = "An opinion should be the result of thought, " - "not a substitute for it."; - - if (argc != 4) { - fprintf (stderr, "Invalid argument\n"); - return 1; - } - - hostname = argv[1]; - volname = argv[2]; - logfile = argv[3]; - - fs = glfs_new (volname); - if (!fs) - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_new", ret, out); - - ret = glfs_set_volfile_server (fs, "tcp", hostname, 24007); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_set_volfile_server", ret, out); - - ret = glfs_set_logging (fs, logfile, 7); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_set_logging", ret, out); - - ret = glfs_init (fs); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_init", ret, out); - - fd1 = glfs_creat(fs, filename, flags, 0644); - if (fd1 == NULL) { - ret = -1; - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_creat", ret, out); - } - - ret = glfs_write (fd1, buff, strlen (buff), flags); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_write", ret, out); - - fd2 = glfs_dup(fd1); - if (fd2 == NULL) { - ret = -1; - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_dup", ret, out); - } - - ret = glfs_lseek (fd2, 0, SEEK_SET); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_lseek", ret, out); + int ret = -1; + int flags = O_RDWR | O_SYNC; + glfs_t *fs = NULL; + glfs_fd_t *fd1 = NULL; + glfs_fd_t *fd2 = NULL; + char *volname = NULL; + char *logfile = NULL; + char *hostname = NULL; + const char *filename = "file_tmp"; + const char *buff = + "An opinion should be the result of thought, " + "not a substitute for it."; + + if (argc != 4) { + fprintf(stderr, "Invalid argument\n"); + return 1; + } + + hostname = argv[1]; + volname = argv[2]; + logfile = argv[3]; + + fs = glfs_new(volname); + if (!fs) + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_new", ret, out); + + ret = glfs_set_volfile_server(fs, "tcp", hostname, 24007); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_set_volfile_server", ret, out); + + ret = glfs_set_logging(fs, logfile, 7); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_set_logging", ret, out); + + ret = glfs_init(fs); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_init", ret, out); + + fd1 = glfs_creat(fs, filename, flags, 0644); + if (fd1 == NULL) { + ret = -1; + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_creat", ret, out); + } + + ret = glfs_write(fd1, buff, strlen(buff), flags); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_write", ret, out); + + fd2 = glfs_dup(fd1); + if (fd2 == NULL) { + ret = -1; + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_dup", ret, out); + } + + ret = glfs_lseek(fd2, 0, SEEK_SET); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_lseek", ret, out); out: - if (fd1 != NULL) - glfs_close(fd1); - if (fd2 != NULL) - glfs_close(fd2); - if (fs) { - ret = glfs_fini(fs); - if (ret) - fprintf (stderr, "glfs_fini(fs) returned %d\n", ret); - } - - return ret; + if (fd1 != NULL) + glfs_close(fd1); + if (fd2 != NULL) + glfs_close(fd2); + if (fs) { + ret = glfs_fini(fs); + if (ret) + fprintf(stderr, "glfs_fini(fs) returned %d\n", ret); + } + + return ret; } - - diff --git a/tests/basic/gfapi/gfapi-graph-switch-open-fd.t b/tests/basic/gfapi/gfapi-graph-switch-open-fd.t new file mode 100644 index 00000000000..2e666be7ec7 --- /dev/null +++ b/tests/basic/gfapi/gfapi-graph-switch-open-fd.t @@ -0,0 +1,44 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup; + +TEST glusterd + +TEST $CLI volume create $V0 replica 3 ${H0}:$B0/brick{0..2}; +EXPECT 'Created' volinfo_field $V0 'Status'; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0; +TEST touch $M0/sync +logdir=`gluster --print-logdir` + +TEST build_tester $(dirname $0)/gfapi-keep-writing.c -lgfapi + + +#Launch a program to keep doing writes on an fd +./$(dirname $0)/gfapi-keep-writing ${H0} $V0 $logdir/gfapi-async-calls-test.log sync & +p=$! +sleep 1 #Let some writes go through +#Check if graph switch will lead to any pending markers for ever +TEST $CLI volume set $V0 performance.quick-read off +TEST $CLI volume set $V0 performance.io-cache off +TEST $CLI volume set $V0 performance.stat-prefetch off +TEST $CLI volume set $V0 performance.read-ahead off + + +TEST rm -f $M0/sync #Make sure the glfd is closed +TEST wait #Wait for background process to die +#Goal is to check if there is permanent FOOL changelog +sleep 5 +EXPECT "0x000000000000000000000000" afr_get_changelog_xattr $B0/brick0/glfs_test.txt trusted.afr.dirty +EXPECT "0x000000000000000000000000" afr_get_changelog_xattr $B0/brick1/glfs_test.txt trusted.afr.dirty +EXPECT "0x000000000000000000000000" afr_get_changelog_xattr $B0/brick2/glfs_test.txt trusted.afr.dirty + +cleanup_tester $(dirname $0)/gfapi-async-calls-test + +cleanup; diff --git a/tests/basic/gfapi/gfapi-keep-writing.c b/tests/basic/gfapi/gfapi-keep-writing.c new file mode 100644 index 00000000000..91b59cea02b --- /dev/null +++ b/tests/basic/gfapi/gfapi-keep-writing.c @@ -0,0 +1,129 @@ +#include <fcntl.h> +#include <unistd.h> +#include <time.h> +#include <limits.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <glusterfs/api/glfs.h> +#include <glusterfs/api/glfs-handles.h> + +#define LOG_ERR(msg) \ + do { \ + fprintf(stderr, "%s : Error (%s)\n", msg, strerror(errno)); \ + } while (0) + +glfs_t * +init_glfs(const char *hostname, const char *volname, const char *logfile) +{ + int ret = -1; + glfs_t *fs = NULL; + + fs = glfs_new(volname); + if (!fs) { + LOG_ERR("glfs_new failed"); + return NULL; + } + + ret = glfs_set_volfile_server(fs, "tcp", hostname, 24007); + if (ret < 0) { + LOG_ERR("glfs_set_volfile_server failed"); + goto out; + } + + ret = glfs_set_logging(fs, logfile, 7); + if (ret < 0) { + LOG_ERR("glfs_set_logging failed"); + goto out; + } + + ret = glfs_init(fs); + if (ret < 0) { + LOG_ERR("glfs_init failed"); + goto out; + } + + ret = 0; +out: + if (ret) { + glfs_fini(fs); + fs = NULL; + } + + return fs; +} + +int +glfs_test_function(const char *hostname, const char *volname, + const char *logfile, const char *syncfile) +{ + int ret = -1; + int flags = O_CREAT | O_RDWR; + glfs_t *fs = NULL; + glfs_fd_t *glfd = NULL; + const char *buff = "This is from my prog\n"; + const char *filename = "glfs_test.txt"; + struct stat buf = {0}; + + fs = init_glfs(hostname, volname, logfile); + if (fs == NULL) { + LOG_ERR("init_glfs failed"); + return -1; + } + + glfd = glfs_creat(fs, filename, flags, 0644); + if (glfd == NULL) { + LOG_ERR("glfs_creat failed"); + goto out; + } + + while (glfs_stat(fs, syncfile, &buf) == 0) { + ret = glfs_write(glfd, buff, strlen(buff), flags); + if (ret < 0) { + LOG_ERR("glfs_write failed"); + goto out; + } + } + + ret = glfs_close(glfd); + if (ret < 0) { + LOG_ERR("glfs_write failed"); + goto out; + } + +out: + ret = glfs_fini(fs); + if (ret) { + LOG_ERR("glfs_fini failed"); + } + + return ret; +} + +int +main(int argc, char *argv[]) +{ + int ret = 0; + char *hostname = NULL; + char *volname = NULL; + char *logfile = NULL; + char *syncfile = NULL; + + if (argc != 5) { + fprintf(stderr, "Invalid argument\n"); + exit(1); + } + + hostname = argv[1]; + volname = argv[2]; + logfile = argv[3]; + syncfile = argv[4]; + + ret = glfs_test_function(hostname, volname, logfile, syncfile); + if (ret) { + LOG_ERR("glfs_test_function failed"); + } + + return ret; +} diff --git a/tests/basic/gfapi/gfapi-load-volfile.c b/tests/basic/gfapi/gfapi-load-volfile.c index 91d5677bd44..fbfc6045cd7 100644 --- a/tests/basic/gfapi/gfapi-load-volfile.c +++ b/tests/basic/gfapi/gfapi-load-volfile.c @@ -9,57 +9,57 @@ #include <stdio.h> #include <string.h> -#include <api/glfs.h> +#include <glusterfs/api/glfs.h> #define PROGNAME "gfapi-load-volfile" void usage(FILE *output) { - fprintf(output, "Usage: " PROGNAME " <volfile>\n"); + fprintf(output, "Usage: " PROGNAME " <volfile>\n"); } void main(int argc, char **argv) { - int ret = 0; - glfs_t *fs = NULL; + int ret = 0; + glfs_t *fs = NULL; - if (argc != 2) { - usage(stderr); - exit(EXIT_FAILURE); - } + if (argc != 2) { + usage(stderr); + exit(EXIT_FAILURE); + } - if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "-h")) { - usage(stdout); - exit(EXIT_SUCCESS); - } + if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "-h")) { + usage(stdout); + exit(EXIT_SUCCESS); + } - fs = glfs_new(PROGNAME); - if (!fs) { - perror("glfs_new failed"); - exit(EXIT_FAILURE); - } + fs = glfs_new(PROGNAME); + if (!fs) { + perror("glfs_new failed"); + exit(EXIT_FAILURE); + } - glfs_set_logging(fs, PROGNAME ".log", 9); + glfs_set_logging(fs, PROGNAME ".log", 9); - ret = glfs_set_volfile(fs, argv[1]); - if (ret) { - perror("glfs_set_volfile failed"); - ret = EXIT_FAILURE; - goto out; - } + ret = glfs_set_volfile(fs, argv[1]); + if (ret) { + perror("glfs_set_volfile failed"); + ret = EXIT_FAILURE; + goto out; + } - ret = glfs_init(fs); - if (ret) { - perror("glfs_init failed"); - ret = EXIT_FAILURE; - goto out; - } + ret = glfs_init(fs); + if (ret) { + perror("glfs_init failed"); + ret = EXIT_FAILURE; + goto out; + } - ret = EXIT_SUCCESS; + ret = EXIT_SUCCESS; out: - glfs_fini(fs); + glfs_fini(fs); - exit(ret); + exit(ret); } diff --git a/tests/basic/gfapi/gfapi-ssl-load-volfile-test.c b/tests/basic/gfapi/gfapi-ssl-load-volfile-test.c new file mode 100644 index 00000000000..7beb8dd1fe4 --- /dev/null +++ b/tests/basic/gfapi/gfapi-ssl-load-volfile-test.c @@ -0,0 +1,127 @@ +#include <fcntl.h> +#include <unistd.h> +#include <time.h> +#include <limits.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <glusterfs/api/glfs.h> +#include <glusterfs/api/glfs-handles.h> + +#define LOG_ERR(msg) \ + do { \ + fprintf(stderr, "%s : Error (%s)\n", msg, strerror(errno)); \ + } while (0) + +glfs_t * +init_glfs(const char *hostname, const char *volname, const char *volfile, + const char *logfile) +{ + int ret = -1; + glfs_t *fs = NULL; + + fs = glfs_new(volname); + if (!fs) { + LOG_ERR("glfs_new failed"); + return NULL; + } + + ret = glfs_set_volfile(fs, volfile); + if (ret < 0) { + LOG_ERR("glfs_set_volfile failed"); + goto out; + } + + ret = glfs_set_logging(fs, logfile, 7); + if (ret < 0) { + LOG_ERR("glfs_set_logging failed"); + goto out; + } + + ret = glfs_init(fs); + if (ret < 0) { + LOG_ERR("glfs_init failed"); + goto out; + } + + ret = 0; +out: + if (ret) { + glfs_fini(fs); + fs = NULL; + } + + return fs; +} + +int +glfs_test_function(const char *hostname, const char *volname, + const char *volfile, const char *logfile) +{ + int ret = -1; + int flags = O_CREAT | O_RDWR; + glfs_t *fs = NULL; + glfs_fd_t *glfd = NULL; + const char *buff = "This is from my prog\n"; + const char *filename = "glfs_test.txt"; + + fs = init_glfs(hostname, volname, volfile, logfile); + if (fs == NULL) { + LOG_ERR("init_glfs failed"); + return -1; + } + + glfd = glfs_creat(fs, filename, flags, 0644); + if (glfd == NULL) { + LOG_ERR("glfs_creat failed"); + goto out; + } + + ret = glfs_write(glfd, buff, strlen(buff), flags); + if (ret < 0) { + LOG_ERR("glfs_write failed"); + goto out; + } + + ret = glfs_close(glfd); + if (ret < 0) { + LOG_ERR("glfs_write failed"); + goto out; + } + +out: + ret = glfs_fini(fs); + if (ret) { + LOG_ERR("glfs_fini failed"); + } + + return ret; +} + +int +main(int argc, char *argv[]) +{ + int ret = 0; + char *hostname = NULL; + char *volname = NULL; + char *volfile = NULL; + char *logfile = NULL; + + if (argc != 5) { + fprintf(stderr, "Invalid argument\n"); + exit(1); + } + + hostname = argv[1]; + volname = argv[2]; + volfile = argv[3]; + logfile = argv[4]; + + ret = glfs_test_function(hostname, volname, volfile, logfile); + if (ret) { + LOG_ERR("glfs_test_function failed"); + } + + return ret; +} diff --git a/tests/basic/gfapi/gfapi-ssl-load-volfile-test.t b/tests/basic/gfapi/gfapi-ssl-load-volfile-test.t new file mode 100755 index 00000000000..8e94df9d321 --- /dev/null +++ b/tests/basic/gfapi/gfapi-ssl-load-volfile-test.t @@ -0,0 +1,76 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +. $(dirname $0)/../../traps.rc +. $(dirname $0)/../../ssl.rc + +cleanup; + +sed -e "s,@@HOSTNAME@@,${H0},g" -e "s,@@BRICKPATH@@,${B0}/brick1,g" \ + -e "s,@@SSL@@,off,g" \ + $(dirname ${0})/protocol-client-ssl.vol.in \ + > $(dirname ${0})/protocol-client-ssl.vol + +TEST create_self_signed_certs + +TEST glusterd + +TEST $CLI volume create $V0 $H0:$B0/brick1; +EXPECT 'Created' volinfo_field $V0 'Status'; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" online_brick_count + +logdir=`gluster --print-logdir` + +TEST build_tester $(dirname $0)/gfapi-ssl-load-volfile-test.c -lgfapi + +# Run test without I/O or management encryption +TEST $(dirname $0)/gfapi-ssl-load-volfile-test $H0 $V0 \ + $(dirname ${0})/protocol-client-ssl.vol \ + $logdir/gfapi-ssl-load-volfile-test.log + +# Enable management encryption +touch $GLUSTERD_WORKDIR/secure-access + +killall_gluster + +TEST glusterd +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" online_brick_count + +# Run test with management encryption (No I/O encryption) +TEST $(dirname $0)/gfapi-ssl-load-volfile-test $H0 $V0 \ + $(dirname ${0})/protocol-client-ssl.vol \ + $logdir/gfapi-ssl-load-volfile-test.log + +# Enable I/O encryption +TEST $CLI volume set $V0 server.ssl on + +killall_gluster + +sed -e "s,@@HOSTNAME@@,${H0},g" -e "s,@@BRICKPATH@@,${B0}/brick1,g" \ + -e "s,@@SSL@@,on,g" \ + $(dirname ${0})/protocol-client-ssl.vol.in \ + > $(dirname ${0})/protocol-client-ssl.vol + +TEST glusterd +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" online_brick_count + +# Run test without I/O or management encryption +TEST $(dirname $0)/gfapi-ssl-load-volfile-test $H0 $V0 \ + $(dirname ${0})/protocol-client-ssl.vol \ + $logdir/gfapi-ssl-load-volfile-test.log + +cleanup_tester $(dirname $0)/gfapi-ssl-load-volfile-test + +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 + +cleanup; + +# NetBSD build scripts are not up to date therefore this test +# is failing in NetBSD. Therefore skipping the test in NetBSD +# as of now. +#G_TESTDEF_TEST_STATUS_NETBSD7=KNOWN_ISSUE,BUG=000000 diff --git a/tests/basic/gfapi/gfapi-ssl-test.c b/tests/basic/gfapi/gfapi-ssl-test.c index 41126bdc6db..a27b5233702 100644 --- a/tests/basic/gfapi/gfapi-ssl-test.c +++ b/tests/basic/gfapi/gfapi-ssl-test.c @@ -9,118 +9,116 @@ #include <glusterfs/api/glfs.h> #include <glusterfs/api/glfs-handles.h> -#define LOG_ERR(msg) do { \ - fprintf (stderr, "%s : Error (%s)\n", msg, strerror (errno)); \ - } while (0) +#define LOG_ERR(msg) \ + do { \ + fprintf(stderr, "%s : Error (%s)\n", msg, strerror(errno)); \ + } while (0) glfs_t * -init_glfs (const char *hostname, const char *volname, - const char *logfile) +init_glfs(const char *hostname, const char *volname, const char *logfile) { - int ret = -1; - glfs_t *fs = NULL; - - fs = glfs_new (volname); - if (!fs) { - LOG_ERR ("glfs_new failed"); - return NULL; - } - - ret = glfs_set_volfile_server (fs, "tcp", hostname, 24007); - if (ret < 0) { - LOG_ERR ("glfs_set_volfile_server failed"); - goto out; - } - - ret = glfs_set_logging (fs, logfile, 7); - if (ret < 0) { - LOG_ERR ("glfs_set_logging failed"); - goto out; - } - - ret = glfs_init (fs); - if (ret < 0) { - LOG_ERR ("glfs_init failed"); - goto out; - } - - ret = 0; + int ret = -1; + glfs_t *fs = NULL; + + fs = glfs_new(volname); + if (!fs) { + LOG_ERR("glfs_new failed"); + return NULL; + } + + ret = glfs_set_volfile_server(fs, "tcp", hostname, 24007); + if (ret < 0) { + LOG_ERR("glfs_set_volfile_server failed"); + goto out; + } + + ret = glfs_set_logging(fs, logfile, 7); + if (ret < 0) { + LOG_ERR("glfs_set_logging failed"); + goto out; + } + + ret = glfs_init(fs); + if (ret < 0) { + LOG_ERR("glfs_init failed"); + goto out; + } + + ret = 0; out: - if (ret) { - glfs_fini (fs); - fs = NULL; - } + if (ret) { + glfs_fini(fs); + fs = NULL; + } - return fs; + return fs; } int -glfs_test_function (const char *hostname, const char *volname, - const char *logfile) +glfs_test_function(const char *hostname, const char *volname, + const char *logfile) { - int ret = -1; - int flags = O_CREAT | O_RDWR; - glfs_t *fs = NULL; - glfs_fd_t *glfd = NULL; - const char *buff = "This is from my prog\n"; - const char *filename = "glfs_test.txt"; - - fs = init_glfs (hostname, volname, logfile); - if (fs == NULL) { - LOG_ERR ("init_glfs failed"); - return -1; - } - - glfd = glfs_creat (fs, filename, flags, 0644); - if (glfd == NULL) { - LOG_ERR ("glfs_creat failed"); - goto out; - } - - ret = glfs_write (glfd, buff, strlen (buff), flags); - if (ret < 0) { - LOG_ERR ("glfs_write failed"); - goto out; - } - - ret = glfs_close (glfd); - if (ret < 0) { - LOG_ERR ("glfs_write failed"); - goto out; - } + int ret = -1; + int flags = O_CREAT | O_RDWR; + glfs_t *fs = NULL; + glfs_fd_t *glfd = NULL; + const char *buff = "This is from my prog\n"; + const char *filename = "glfs_test.txt"; + + fs = init_glfs(hostname, volname, logfile); + if (fs == NULL) { + LOG_ERR("init_glfs failed"); + return -1; + } + + glfd = glfs_creat(fs, filename, flags, 0644); + if (glfd == NULL) { + LOG_ERR("glfs_creat failed"); + goto out; + } + + ret = glfs_write(glfd, buff, strlen(buff), flags); + if (ret < 0) { + LOG_ERR("glfs_write failed"); + goto out; + } + + ret = glfs_close(glfd); + if (ret < 0) { + LOG_ERR("glfs_write failed"); + goto out; + } out: - ret = glfs_fini (fs); - if (ret) { - LOG_ERR ("glfs_fini failed"); - } + ret = glfs_fini(fs); + if (ret) { + LOG_ERR("glfs_fini failed"); + } - return ret; + return ret; } int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { - int ret = 0; - char *hostname = NULL; - char *volname = NULL; - char *logfile = NULL; - - if (argc != 4) { - fprintf (stderr, "Invalid argument\n"); - exit(1); - } - - hostname = argv[1]; - volname = argv[2]; - logfile = argv[3]; - - ret = glfs_test_function (hostname, volname, logfile); - if (ret) { - LOG_ERR ("glfs_test_function failed"); - } - - return ret; + int ret = 0; + char *hostname = NULL; + char *volname = NULL; + char *logfile = NULL; + + if (argc != 4) { + fprintf(stderr, "Invalid argument\n"); + exit(1); + } + + hostname = argv[1]; + volname = argv[2]; + logfile = argv[3]; + + ret = glfs_test_function(hostname, volname, logfile); + if (ret) { + LOG_ERR("glfs_test_function failed"); + } + + return ret; } - - diff --git a/tests/basic/gfapi/gfapi-statx-basic.c b/tests/basic/gfapi/gfapi-statx-basic.c new file mode 100644 index 00000000000..a4943fa0fd1 --- /dev/null +++ b/tests/basic/gfapi/gfapi-statx-basic.c @@ -0,0 +1,184 @@ +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <stdbool.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <glusterfs/api/glfs.h> + +#define VALIDATE_AND_GOTO_LABEL_ON_ERROR(func, ret, label) \ + do { \ + if (ret < 0) { \ + fprintf(stderr, "%s : returned error %d (%s)\n", func, ret, \ + strerror(errno)); \ + goto label; \ + } \ + } while (0) + +#define GOTO_LABEL_ON_FALSE(compstr, ret, label) \ + do { \ + if (ret == false) { \ + fprintf(stderr, "%s : comparison failed!\n", compstr); \ + goto label; \ + } \ + } while (0) + +#define WRITE_SIZE 513 +#define TRUNC_SIZE 4096 + +/* Using private function and hence providing a forward declation in sync with +code in glfs-internal.h */ +int +glfs_statx(struct glfs *fs, const char *path, unsigned int mask, + struct glfs_stat *statxbuf); + +int +main(int argc, char *argv[]) +{ + int ret = -1; + int flags = O_RDWR | O_SYNC; + glfs_t *fs = NULL; + glfs_fd_t *fd1 = NULL; + char *volname = NULL; + char *logfile = NULL; + const char *filename = "file_tmp"; + const char buff[WRITE_SIZE]; + struct stat sb; + unsigned int mask; + struct glfs_stat statx; + bool bret; + + if (argc != 3) { + fprintf(stderr, "Invalid argument\n"); + fprintf(stderr, "Usage: %s <volname> <logfile>\n", argv[0]); + return 1; + } + + volname = argv[1]; + logfile = argv[2]; + + fs = glfs_new(volname); + if (!fs) + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_new", ret, out); + + ret = glfs_set_volfile_server(fs, "tcp", "localhost", 24007); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_set_volfile_server", ret, out); + + ret = glfs_set_logging(fs, logfile, 7); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_set_logging", ret, out); + + ret = glfs_init(fs); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_init", ret, out); + + fd1 = glfs_creat(fs, filename, flags, 0644); + if (fd1 == NULL) { + ret = -1; + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_creat", ret, out); + } + + ret = glfs_truncate(fs, filename, TRUNC_SIZE); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_truncate", ret, out); + + ret = glfs_write(fd1, buff, WRITE_SIZE, flags); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_write", ret, out); + + ret = glfs_fstat(fd1, &sb); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_fstat", ret, out); + + if (sb.st_size != TRUNC_SIZE) { + fprintf(stderr, "wrong size %jd should be %jd\n", (intmax_t)sb.st_size, + (intmax_t)2048); + ret = -1; + goto out; + } + + glfs_close(fd1); + fd1 = NULL; + + /* TEST 1: Invalid mask to statx */ + mask = 0xfafadbdb; + ret = glfs_statx(fs, filename, mask, NULL); + if (ret == 0 || ((ret == -1) && (errno != EINVAL))) { + fprintf(stderr, + "Invalid args passed, but error returned is" + " incorrect (ret - %d, errno - %d)\n", + ret, errno); + ret = -1; + goto out; + } + ret = 0; + + /* TEST 2: Call statx and validate fields against prior fstat data */ + /* NOTE: This fails, as iatt->ia_flags are not carried through the stack, + * for example if mdc_to_iatt is invoked to serve cached stat, we will loose + * the flags. */ + mask = GLFS_STAT_ALL; + ret = glfs_statx(fs, filename, mask, &statx); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_statx", ret, out); + + if ((statx.glfs_st_mask & GLFS_STAT_BASIC_STATS) != GLFS_STAT_BASIC_STATS) { + fprintf(stderr, "Invalid glfs_st_mask, expecting 0x%x got 0x%x\n", + GLFS_STAT_ALL, statx.glfs_st_mask); + ret = -1; + goto out; + } + + bret = (sb.st_ino == statx.glfs_st_ino); + GOTO_LABEL_ON_FALSE("(sb.st_ino == statx.glfs_st_ino)", bret, out); + + bret = (sb.st_mode == statx.glfs_st_mode); + GOTO_LABEL_ON_FALSE("(sb.st_mode == statx.glfs_st_mode)", bret, out); + + bret = (sb.st_nlink == statx.glfs_st_nlink); + GOTO_LABEL_ON_FALSE("(sb.st_nlink == statx.glfs_st_nlink)", bret, out); + + bret = (sb.st_uid == statx.glfs_st_uid); + GOTO_LABEL_ON_FALSE("(sb.st_uid == statx.glfs_st_uid)", bret, out); + + bret = (sb.st_gid == statx.glfs_st_gid); + GOTO_LABEL_ON_FALSE("(sb.st_gid == statx.glfs_st_gid)", bret, out); + + bret = (sb.st_size == statx.glfs_st_size); + GOTO_LABEL_ON_FALSE("(sb.st_size == statx.glfs_st_size)", bret, out); + + bret = (sb.st_blksize == statx.glfs_st_blksize); + GOTO_LABEL_ON_FALSE("(sb.st_blksize == statx.glfs_st_blksize)", bret, out); + + bret = (sb.st_blocks == statx.glfs_st_blocks); + GOTO_LABEL_ON_FALSE("(sb.st_blocks == statx.glfs_st_blocks)", bret, out); + + bret = (!memcmp(&sb.st_atim, &statx.glfs_st_atime, + sizeof(struct timespec))); + GOTO_LABEL_ON_FALSE("(sb.st_atim == statx.glfs_st_atime)", bret, out); + + bret = (!memcmp(&sb.st_mtim, &statx.glfs_st_mtime, + sizeof(struct timespec))); + GOTO_LABEL_ON_FALSE("(sb.st_mtim == statx.glfs_st_mtime)", bret, out); + + bret = (!memcmp(&sb.st_ctim, &statx.glfs_st_ctime, + sizeof(struct timespec))); + GOTO_LABEL_ON_FALSE("(sb.st_ctim == statx.glfs_st_ctime)", bret, out); + + /* TEST 3: Check if partial masks are accepted */ + mask = GLFS_STAT_TYPE | GLFS_STAT_UID | GLFS_STAT_GID; + ret = glfs_statx(fs, filename, mask, &statx); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_statx", ret, out); + + /* We currently still return all stats, as is acceptable based on the API + * definition in the header (and in statx as well) */ + if ((statx.glfs_st_mask & GLFS_STAT_BASIC_STATS) != GLFS_STAT_BASIC_STATS) { + fprintf(stderr, "Invalid glfs_st_mask, expecting 0x%x got 0x%x\n", + GLFS_STAT_ALL, statx.glfs_st_mask); + ret = -1; + goto out; + } +out: + if (fd1 != NULL) + glfs_close(fd1); + if (fs) { + (void)glfs_fini(fs); + } + + return ret; +} diff --git a/tests/basic/gfapi/gfapi-statx-basic.t b/tests/basic/gfapi/gfapi-statx-basic.t new file mode 100755 index 00000000000..d9acbce2f99 --- /dev/null +++ b/tests/basic/gfapi/gfapi-statx-basic.t @@ -0,0 +1,30 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup; + +TEST glusterd + +TEST $CLI volume create $V0 ${H0}:$B0/brick1; +EXPECT 'Created' volinfo_field $V0 'Status'; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +# NOTE: Test is passing due to very specific volume configuration +# Disable md-cache, as it does not save and return ia_flags from iatt +# This is possibly going to be true of other xlators as well (ec/afr), need to +# ensure these are fixed, or hack statx to return all basic attrs anyway. +TEST $CLI volume set $V0 performance.md-cache-timeout 0 + +logdir=`gluster --print-logdir` + +build_tester $(dirname $0)/gfapi-statx-basic.c -lgfapi + +TEST ./$(dirname $0)/gfapi-statx-basic $V0 $logdir/gfapi-statx-basic.log + +cleanup_tester $(dirname $0)/gfapi-statx-basic + +cleanup; diff --git a/tests/basic/gfapi/gfapi-trunc.c b/tests/basic/gfapi/gfapi-trunc.c index af187e50c78..769f6cfa1d9 100644 --- a/tests/basic/gfapi/gfapi-trunc.c +++ b/tests/basic/gfapi/gfapi-trunc.c @@ -5,86 +5,85 @@ #include <glusterfs/api/glfs.h> #include <glusterfs/api/glfs-handles.h> -#define VALIDATE_AND_GOTO_LABEL_ON_ERROR(func, ret, label) do { \ - if (ret < 0) { \ - fprintf (stderr, "%s : returned error %d (%s)\n", \ - func, ret, strerror (errno)); \ - goto label; \ - } \ - } while (0) - -#define WRITE_SIZE 4096 -#define TRUNC_SIZE 1234 +#define VALIDATE_AND_GOTO_LABEL_ON_ERROR(func, ret, label) \ + do { \ + if (ret < 0) { \ + fprintf(stderr, "%s : returned error %d (%s)\n", func, ret, \ + strerror(errno)); \ + goto label; \ + } \ + } while (0) + +#define WRITE_SIZE 4096 +#define TRUNC_SIZE 1234 /* Make sure TRUNC_SIZE is smaller than WRITE_SIZE at compile time. */ -typedef char _size_check[WRITE_SIZE-TRUNC_SIZE]; +typedef char _size_check[WRITE_SIZE - TRUNC_SIZE]; int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { - int ret = -1; - int flags = O_RDWR|O_SYNC; - glfs_t *fs = NULL; - glfs_fd_t *fd1 = NULL; - char *volname = NULL; - char *logfile = NULL; - const char *filename = "file_tmp"; - const char buff[WRITE_SIZE]; - struct stat sb; - - if (argc != 3) { - fprintf (stderr, "Invalid argument\n"); - return 1; - } - - volname = argv[1]; - logfile = argv[2]; - - fs = glfs_new (volname); - if (!fs) - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_new", ret, out); - - ret = glfs_set_volfile_server (fs, "tcp", "localhost", 24007); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_set_volfile_server", ret, out); - - ret = glfs_set_logging (fs, logfile, 7); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_set_logging", ret, out); - - ret = glfs_init (fs); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_init", ret, out); - - fd1 = glfs_creat(fs, filename, flags, 0644); - if (fd1 == NULL) { - ret = -1; - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_creat", ret, out); - } - - ret = glfs_write (fd1, buff, WRITE_SIZE, flags); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_write", ret, out); - - ret = glfs_truncate (fs, filename, TRUNC_SIZE); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_truncate", ret, out); - - ret = glfs_fstat (fd1, &sb); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_fstat", ret, out); - - if (sb.st_size != TRUNC_SIZE) { - fprintf (stderr, "wrong size %jd should be %jd\n", - (intmax_t)sb.st_size, (intmax_t)2048); - ret = -1; - } + int ret = -1; + int flags = O_RDWR | O_SYNC; + glfs_t *fs = NULL; + glfs_fd_t *fd1 = NULL; + char *volname = NULL; + char *logfile = NULL; + const char *filename = "file_tmp"; + const char buff[WRITE_SIZE]; + struct stat sb; + + if (argc != 3) { + fprintf(stderr, "Invalid argument\n"); + return 1; + } + + volname = argv[1]; + logfile = argv[2]; + + fs = glfs_new(volname); + if (!fs) + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_new", ret, out); + + ret = glfs_set_volfile_server(fs, "tcp", "localhost", 24007); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_set_volfile_server", ret, out); + + ret = glfs_set_logging(fs, logfile, 7); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_set_logging", ret, out); + + ret = glfs_init(fs); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_init", ret, out); + + fd1 = glfs_creat(fs, filename, flags, 0644); + if (fd1 == NULL) { + ret = -1; + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_creat", ret, out); + } + + ret = glfs_write(fd1, buff, WRITE_SIZE, flags); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_write", ret, out); + + ret = glfs_truncate(fs, filename, TRUNC_SIZE); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_truncate", ret, out); + + ret = glfs_fstat(fd1, &sb); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_fstat", ret, out); + + if (sb.st_size != TRUNC_SIZE) { + fprintf(stderr, "wrong size %jd should be %jd\n", (intmax_t)sb.st_size, + (intmax_t)2048); + ret = -1; + } out: - if (fd1 != NULL) - glfs_close(fd1); - if (fs) { - /* - * If this fails (as it does on Special Snowflake NetBSD for no - * good reason), it shouldn't affect the result of the test. - */ - (void) glfs_fini(fs); - } - - return ret; + if (fd1 != NULL) + glfs_close(fd1); + if (fs) { + /* + * If this fails (as it does on Special Snowflake NetBSD for no + * good reason), it shouldn't affect the result of the test. + */ + (void)glfs_fini(fs); + } + + return ret; } - - diff --git a/tests/basic/gfapi/glfd-lkowner.c b/tests/basic/gfapi/glfd-lkowner.c index 031a076683c..ec0429dc3c4 100644 --- a/tests/basic/gfapi/glfd-lkowner.c +++ b/tests/basic/gfapi/glfd-lkowner.c @@ -13,200 +13,202 @@ int gfapi = 1; -#define LOG_ERR(func, ret) do { \ - if (ret != 0) { \ - fprintf (stderr, "%s : returned error %d (%s)\n", \ - func, ret, strerror (errno)); \ - goto out; \ - } else { \ - fprintf (stderr, "%s : returned %d\n", func, ret); \ - } \ - } while (0) +#define LOG_ERR(func, ret) \ + do { \ + if (ret != 0) { \ + fprintf(stderr, "%s : returned error %d (%s)\n", func, ret, \ + strerror(errno)); \ + goto out; \ + } else { \ + fprintf(stderr, "%s : returned %d\n", func, ret); \ + } \ + } while (0) char lownera[8] = "lownera", lownerb[8] = "lownerb"; char lownerc[8] = "lownerc"; -int lock_test (glfs_fd_t *glfd1, glfs_fd_t *glfd2, bool should_fail, - int l1_start, int l1_len, char *l1_owner, int lo1_len, - int l2_start, int l2_len, char *l2_owner, int lo2_len) +int +lock_test(glfs_fd_t *glfd1, glfs_fd_t *glfd2, bool should_fail, int l1_start, + int l1_len, char *l1_owner, int lo1_len, int l2_start, int l2_len, + char *l2_owner, int lo2_len) { - int ret = -1, f_ret = -1; - struct flock lock1 = {0, }, lock2 = {0, }; + int ret = -1, f_ret = -1; + struct flock lock1 = + { + 0, + }, + lock2 = { + 0, + }; lock1: - if (!glfd1) - goto lock2; + if (!glfd1) + goto lock2; - /* lock on glfd1 */ - lock1.l_type = F_WRLCK; - lock1.l_whence = SEEK_SET; - lock1.l_start = l1_start; - lock1.l_len = l1_len; + /* lock on glfd1 */ + lock1.l_type = F_WRLCK; + lock1.l_whence = SEEK_SET; + lock1.l_start = l1_start; + lock1.l_len = l1_len; - ret = glfs_fd_set_lkowner (glfd1, l1_owner, lo1_len); - LOG_ERR ("glfs_fd_set_lkowner on glfd1", ret); + ret = glfs_fd_set_lkowner(glfd1, l1_owner, lo1_len); + LOG_ERR("glfs_fd_set_lkowner on glfd1", ret); - ret = glfs_posix_lock (glfd1, F_SETLK, &lock1); - LOG_ERR ("glfs_posix_lock on glfd1", ret); + ret = glfs_posix_lock(glfd1, F_SETLK, &lock1); + LOG_ERR("glfs_posix_lock on glfd1", ret); lock2: - if (!glfd2) - goto out; - - /* lock on glfd2 */ - lock2.l_type = F_WRLCK; - lock2.l_whence = SEEK_SET; - lock2.l_start = l2_start; - lock2.l_len = l2_len; - - ret = glfs_fd_set_lkowner (glfd2, l2_owner, lo2_len); - LOG_ERR ("glfs_fd_set_lkowner on glfd2", ret); - - ret = glfs_posix_lock (glfd2, F_SETLK, &lock2); - - if (should_fail && ret) { - f_ret = 0; - } else if (!ret && !should_fail) { - f_ret = 0; - } else { - f_ret = -1; - } + if (!glfd2) + goto out; + + /* lock on glfd2 */ + lock2.l_type = F_WRLCK; + lock2.l_whence = SEEK_SET; + lock2.l_start = l2_start; + lock2.l_len = l2_len; + + ret = glfs_fd_set_lkowner(glfd2, l2_owner, lo2_len); + LOG_ERR("glfs_fd_set_lkowner on glfd2", ret); + + ret = glfs_posix_lock(glfd2, F_SETLK, &lock2); + + if (should_fail && ret) { + f_ret = 0; + } else if (!ret && !should_fail) { + f_ret = 0; + } else { + f_ret = -1; + } out: - fprintf (stderr, "Lock test on glfd1 (start(%d), len(%d)," - " lk_owner(%s)) and glfd2 (start(%d), len(%d), " - "lk_owner(%s)) - expected(%s) - result(%s)\n", - l1_start, l1_len, l1_owner, l2_start, l2_len, l2_owner, - (should_fail ? "FAIL" : "SUCCESS"), - (ret ? "FAIL" : "SUCCESS")); - return f_ret; + fprintf(stderr, + "Lock test on glfd1 (start(%d), len(%d)," + " lk_owner(%s)) and glfd2 (start(%d), len(%d), " + "lk_owner(%s)) - expected(%s) - result(%s)\n", + l1_start, l1_len, l1_owner, l2_start, l2_len, l2_owner, + (should_fail ? "FAIL" : "SUCCESS"), (ret ? "FAIL" : "SUCCESS")); + return f_ret; } int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { - glfs_t *fs = NULL; - int ret = 0, i, status = 0; - glfs_fd_t *fd1 = NULL; - glfs_fd_t *fd2 = NULL; - glfs_fd_t *fd3 = NULL; - char *filename = "file_tmp"; - char *volname = NULL; - char *logfile = NULL; - char *hostname = NULL; - - if (argc != 4) { - fprintf (stderr, "Invalid argument\n"); - exit(1); - } - - hostname = argv[1]; - volname = argv[2]; - logfile = argv[3]; - - fs = glfs_new (volname); - if (!fs) { - fprintf (stderr, "glfs_new: returned NULL\n"); - return -1; - } - - ret = glfs_set_volfile_server (fs, "tcp", hostname, 24007); - LOG_ERR("glfs_set_volfile_server", ret); - - ret = glfs_set_logging (fs, logfile, 7); - LOG_ERR("glfs_set_logging", ret); - - ret = glfs_init (fs); - LOG_ERR("glfs_init", ret); - - fd1 = glfs_creat(fs, filename, O_RDWR|O_SYNC, 0644); - if (fd1 <= 0) { - ret = -1; - LOG_ERR ("glfs_creat", ret); - } - fprintf (stderr, "glfs-create fd1 - %d\n", fd1); - - fd2 = glfs_dup(fd1); - fprintf (stderr, "glfs-dup fd2 - %d\n", fd2); - - fd3 = glfs_open(fs, filename, O_RDWR|O_SYNC); - if (fd2 <= 0) { - ret = -1; - LOG_ERR ("glfs_open", ret); - } - fprintf (stderr, "glfs-open fd3 - %d\n", fd3); - - /* TEST 1: Conflicting ranges, same lk_owner - * lock1 (0, 10, lownera) - * lock2 (5, 10, lownera) - * Expected: should not fail but get merged - */ - ret = lock_test (fd1, fd2, false, 0, 10, lownera, 8, - 5, 10, lownera, 8); - LOG_ERR ("==== glfs_lock_test_1", ret); - - /* TEST 2: Conflicting ranges, different lk_owner - * lock1 (0, 10, lownera) - already taken - * lock2 (5, 10, lownerb) - * Expected: should fail and not get merged - */ - ret = lock_test (NULL, fd2, true, 0, 10, lownera, 8, - 5, 10, lownerb, 8); - LOG_ERR ("==== glfs_lock_test_2", ret); - - /* TEST 3: Different ranges, same lk_owner - * lock1 (0, 10, lownera) - already taken - * lock2 (30, 10, lownera) - * Expected: should not fail - */ - ret = lock_test (NULL, fd2, false, 0, 10, lownera, 8, - 30, 10, lownera, 8); - LOG_ERR ("==== glfs_lock_test_3", ret); - - /* TEST 4: Conflicting ranges, different lk_owner - * lock1 (0, 10, lownera) - already taken - * lock2 (50, 10, lownerb) - * Expected: should not fail - */ - ret = lock_test (NULL, fd2, false, 0, 10, lownera, 8, - 50, 10, lownerb, 8); - LOG_ERR ("==== glfs_lock_test_4", ret); - - /* TEST 5: Close fd1 & retry TEST2 - * lock1 (not applicable) - * lock2 (5, 10, lownerb) - * Expected: should succeed now - */ - ret = glfs_close(fd1); - LOG_ERR ("glfs_close", ret); - - ret = lock_test (NULL, fd2, false, 0, 10, lownera, 8, - 5, 10, lownerb, 8); - LOG_ERR ("==== glfs_lock_test_5", ret); - - /* TEST 6: Check closing fd1 doesn't flush fd2 locks - * retry TEST 4 but with fd2 and fd3. - * lock1 (50, 10, lownerb) - already taken - * lock2 (55, 10, lownerc) - * Expected: should fail - */ - ret = lock_test (NULL, fd3, true, 50, 10, lownerb, 8, - 55, 10, lownerc, 8); - LOG_ERR ("==== glfs_lock_test_6", ret); + glfs_t *fs = NULL; + int ret = 0, i, status = 0; + glfs_fd_t *fd1 = NULL; + glfs_fd_t *fd2 = NULL; + glfs_fd_t *fd3 = NULL; + char *filename = "file_tmp"; + char *volname = NULL; + char *logfile = NULL; + char *hostname = NULL; + + if (argc != 4) { + fprintf(stderr, "Invalid argument\n"); + exit(1); + } + + hostname = argv[1]; + volname = argv[2]; + logfile = argv[3]; + + fs = glfs_new(volname); + if (!fs) { + fprintf(stderr, "glfs_new: returned NULL\n"); + return -1; + } + + ret = glfs_set_volfile_server(fs, "tcp", hostname, 24007); + LOG_ERR("glfs_set_volfile_server", ret); + + ret = glfs_set_logging(fs, logfile, 7); + LOG_ERR("glfs_set_logging", ret); + + ret = glfs_init(fs); + LOG_ERR("glfs_init", ret); + + fd1 = glfs_creat(fs, filename, O_RDWR | O_SYNC, 0644); + if (fd1 <= 0) { + ret = -1; + LOG_ERR("glfs_creat", ret); + } + fprintf(stderr, "glfs-create fd1 - %d\n", fd1); + + fd2 = glfs_dup(fd1); + fprintf(stderr, "glfs-dup fd2 - %d\n", fd2); + + fd3 = glfs_open(fs, filename, O_RDWR | O_SYNC); + if (fd2 <= 0) { + ret = -1; + LOG_ERR("glfs_open", ret); + } + fprintf(stderr, "glfs-open fd3 - %d\n", fd3); + + /* TEST 1: Conflicting ranges, same lk_owner + * lock1 (0, 10, lownera) + * lock2 (5, 10, lownera) + * Expected: should not fail but get merged + */ + ret = lock_test(fd1, fd2, false, 0, 10, lownera, 8, 5, 10, lownera, 8); + LOG_ERR("==== glfs_lock_test_1", ret); + + /* TEST 2: Conflicting ranges, different lk_owner + * lock1 (0, 10, lownera) - already taken + * lock2 (5, 10, lownerb) + * Expected: should fail and not get merged + */ + ret = lock_test(NULL, fd2, true, 0, 10, lownera, 8, 5, 10, lownerb, 8); + LOG_ERR("==== glfs_lock_test_2", ret); + + /* TEST 3: Different ranges, same lk_owner + * lock1 (0, 10, lownera) - already taken + * lock2 (30, 10, lownera) + * Expected: should not fail + */ + ret = lock_test(NULL, fd2, false, 0, 10, lownera, 8, 30, 10, lownera, 8); + LOG_ERR("==== glfs_lock_test_3", ret); + + /* TEST 4: Conflicting ranges, different lk_owner + * lock1 (0, 10, lownera) - already taken + * lock2 (50, 10, lownerb) + * Expected: should not fail + */ + ret = lock_test(NULL, fd2, false, 0, 10, lownera, 8, 50, 10, lownerb, 8); + LOG_ERR("==== glfs_lock_test_4", ret); + + /* TEST 5: Close fd1 & retry TEST2 + * lock1 (not applicable) + * lock2 (5, 10, lownerb) + * Expected: should succeed now + */ + ret = glfs_close(fd1); + LOG_ERR("glfs_close", ret); + + ret = lock_test(NULL, fd2, false, 0, 10, lownera, 8, 5, 10, lownerb, 8); + LOG_ERR("==== glfs_lock_test_5", ret); + + /* TEST 6: Check closing fd1 doesn't flush fd2 locks + * retry TEST 4 but with fd2 and fd3. + * lock1 (50, 10, lownerb) - already taken + * lock2 (55, 10, lownerc) + * Expected: should fail + */ + ret = lock_test(NULL, fd3, true, 50, 10, lownerb, 8, 55, 10, lownerc, 8); + LOG_ERR("==== glfs_lock_test_6", ret); err: - ret = glfs_close(fd2); - LOG_ERR ("glfs_close", ret); + ret = glfs_close(fd2); + LOG_ERR("glfs_close", ret); - ret = glfs_close(fd3); - LOG_ERR ("glfs_close", ret); + ret = glfs_close(fd3); + LOG_ERR("glfs_close", ret); out: - if (fs) { - ret = glfs_fini(fs); - fprintf (stderr, "glfs_fini(fs) returned %d\n", ret); - } - - if (ret) - exit(1); - exit(0); + if (fs) { + ret = glfs_fini(fs); + fprintf(stderr, "glfs_fini(fs) returned %d\n", ret); + } + + if (ret) + exit(1); + exit(0); } diff --git a/tests/basic/gfapi/glfs-copy-file-range.c b/tests/basic/gfapi/glfs-copy-file-range.c new file mode 100644 index 00000000000..1c5fd81fc87 --- /dev/null +++ b/tests/basic/gfapi/glfs-copy-file-range.c @@ -0,0 +1,180 @@ +/* + Copyright (c) 2018 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <glusterfs/api/glfs.h> +#include <glusterfs/api/glfs-handles.h> +#include <string.h> +#include <time.h> +#include <libgen.h> + +static void +cleanup(glfs_t *fs) +{ + if (!fs) + return; +#if 0 + /* glfs fini path is still racy and crashing the program. Since + * this program any way has to die, we are not going to call fini + * in the released versions. i.e. final builds. For all + * internal testing lets enable this so that glfs_fini code + * path becomes stable. */ + glfs_fini (fs); +#endif +} + +int +main(int argc, char **argv) +{ + glfs_t *fs = NULL; + int ret = -1; + char *volname = NULL; + char *logfilepath = NULL; + char *path_src = NULL; + char *path_dst = NULL; + glfs_fd_t *glfd_in = NULL; + glfs_fd_t *glfd_out = NULL; + char *volfile_server = NULL; + + struct stat stbuf = { + 0, + }; + struct glfs_stat stat_src = { + 0, + }; + struct glfs_stat prestat_dst = { + 0, + }; + struct glfs_stat poststat_dst = { + 0, + }; + size_t len; + + if (argc < 6) { + printf("%s <volume> <log file path> <source> <destination>", argv[0]); + ret = -1; + goto out; + } + + volfile_server = argv[1]; + volname = argv[2]; + logfilepath = argv[3]; + path_src = argv[4]; + path_dst = argv[5]; + + if (path_src[0] != '/') { + fprintf(stderr, "source path %s is not absolute", path_src); + errno = EINVAL; + goto out; + } + + if (path_dst[0] != '/') { + fprintf(stderr, "destination path %s is not absolute", path_dst); + errno = EINVAL; + goto out; + } + + fs = glfs_new(volname); + if (!fs) { + ret = -errno; + fprintf(stderr, "Not able to initialize volume '%s'", volname); + goto out; + } + + ret = glfs_set_volfile_server(fs, "tcp", volfile_server, 24007); + if (ret < 0) { + ret = -errno; + fprintf(stderr, + "Failed to set the volfile server, " + "%s", + strerror(errno)); + goto out; + } + + ret = glfs_set_logging(fs, logfilepath, 7); + if (ret < 0) { + ret = -errno; + fprintf(stderr, + "Failed to set the log file path, " + "%s", + strerror(errno)); + goto out; + } + + ret = glfs_init(fs); + if (ret < 0) { + ret = -errno; + if (errno == ENOENT) { + fprintf(stderr, "Volume %s does not exist", volname); + } else { + fprintf(stderr, + "%s: Not able to fetch " + "volfile from glusterd", + volname); + } + goto out; + } + + glfd_in = glfs_open(fs, path_src, O_RDONLY | O_NONBLOCK); + if (!glfd_in) { + ret = -errno; + goto out; + } else { + printf("OPEN_SRC: opening %s is success\n", path_src); + } + + glfd_out = glfs_creat(fs, path_dst, O_RDWR, 0644); + if (!glfd_out) { + fprintf(stderr, + "FAILED_DST_OPEN: failed to " + "open (create) %s (%s)\n", + path_dst, strerror(errno)); + ret = -errno; + goto out; + } else { + printf("OPEN_DST: opening %s is success\n", path_dst); + } + + ret = glfs_fstat(glfd_in, &stbuf); + if (ret < 0) { + ret = -errno; + goto out; + } else { + printf("FSTAT_SRC: fstat on %s is success\n", path_dst); + } + + len = stbuf.st_size; + + do { + ret = glfs_copy_file_range(glfd_in, NULL, glfd_out, NULL, len, 0, + &stat_src, &prestat_dst, &poststat_dst); + if (ret == -1) { + fprintf(stderr, "copy_file_range failed with %s\n", + strerror(errno)); + ret = -errno; + break; + } else { + printf("copy_file_range successful\n"); + len -= ret; + } + } while (len > 0); + +out: + if (glfd_in) + glfs_close(glfd_in); + if (glfd_out) + glfs_close(glfd_out); + + cleanup(fs); + + return ret; +} diff --git a/tests/basic/gfapi/glfs_h_creat_open.c b/tests/basic/gfapi/glfs_h_creat_open.c new file mode 100644 index 00000000000..7672561e73f --- /dev/null +++ b/tests/basic/gfapi/glfs_h_creat_open.c @@ -0,0 +1,118 @@ +#include <fcntl.h> +#include <unistd.h> +#include <time.h> +#include <limits.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <glusterfs/api/glfs.h> +#include <glusterfs/api/glfs-handles.h> + +#define LOG_ERR(func, ret) \ + do { \ + if (ret != 0) { \ + fprintf(stderr, "%s : returned error ret(%d), errno(%d)\n", func, \ + ret, errno); \ + exit(1); \ + } else { \ + fprintf(stderr, "%s : returned %d\n", func, ret); \ + } \ + } while (0) +#define LOG_IF_NO_ERR(func, ret) \ + do { \ + if (ret == 0) { \ + fprintf(stderr, "%s : hasn't returned error %d\n", func, ret); \ + exit(1); \ + } else { \ + fprintf(stderr, "%s : returned %d\n", func, ret); \ + } \ + } while (0) +int +main(int argc, char *argv[]) +{ + glfs_t *fs = NULL; + int ret = 0; + struct glfs_object *root = NULL, *leaf = NULL; + glfs_fd_t *fd = NULL; + char *filename = "/ro-file"; + struct stat sb = { + 0, + }; + char *logfile = NULL; + char *volname = NULL; + char *hostname = NULL; + char buf[32] = "abcdefghijklmnopqrstuvwxyz012345"; + + fprintf(stderr, "Starting glfs_h_creat_open\n"); + + if (argc != 4) { + fprintf(stderr, "Invalid argument\n"); + exit(1); + } + + hostname = argv[1]; + volname = argv[2]; + logfile = argv[3]; + + fs = glfs_new(volname); + if (!fs) { + fprintf(stderr, "glfs_new: returned NULL\n"); + return 1; + } + + ret = glfs_set_volfile_server(fs, "tcp", hostname, 24007); + LOG_ERR("glfs_set_volfile_server", ret); + + ret = glfs_set_logging(fs, logfile, 7); + LOG_ERR("glfs_set_logging", ret); + + ret = glfs_init(fs); + LOG_ERR("glfs_init", ret); + + sleep(2); + root = glfs_h_lookupat(fs, NULL, "/", &sb, 0); + if (!root) { + ret = -1; + LOG_ERR("glfs_h_lookupat root", ret); + } + leaf = glfs_h_lookupat(fs, root, filename, &sb, 0); + if (!leaf) { + ret = -1; + LOG_IF_NO_ERR("glfs_h_lookupat leaf", ret); + } + + leaf = glfs_h_creat_open(fs, root, filename, O_RDONLY, 00444, &sb, &fd); + if (!leaf || !fd) { + ret = -1; + LOG_ERR("glfs_h_creat leaf", ret); + } + fprintf(stderr, "glfs_h_create_open leaf - %p\n", leaf); + + ret = glfs_write(fd, buf, 32, 0); + if (ret < 0) { + fprintf(stderr, "glfs_write: error writing to file %s, %s\n", filename, + strerror(errno)); + goto out; + } + + ret = glfs_h_getattrs(fs, leaf, &sb); + LOG_ERR("glfs_h_getattrs", ret); + + if (sb.st_size != 32) { + fprintf(stderr, "glfs_write: post size mismatch\n"); + goto out; + } + + fprintf(stderr, "Successfully opened and written to a read-only file \n"); +out: + if (fd) + glfs_close(fd); + + ret = glfs_fini(fs); + LOG_ERR("glfs_fini", ret); + + fprintf(stderr, "End of libgfapi_fini\n"); + + exit(0); +} diff --git a/tests/basic/gfapi/glfs_h_creat_open.t b/tests/basic/gfapi/glfs_h_creat_open.t new file mode 100755 index 00000000000..f24ae7395be --- /dev/null +++ b/tests/basic/gfapi/glfs_h_creat_open.t @@ -0,0 +1,27 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup; + +TEST glusterd + +TEST $CLI volume create $V0 $H0:$B0/brick1; +EXPECT 'Created' volinfo_field $V0 'Status'; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +logdir=`gluster --print-logdir` + +TEST build_tester $(dirname $0)/glfs_h_creat_open.c -lgfapi + +TEST ./$(dirname $0)/glfs_h_creat_open $H0 $V0 $logdir/glfs.log + +cleanup_tester $(dirname $0)/glfs_h_creat_open + +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 + +cleanup; diff --git a/tests/basic/gfapi/glfs_sysrq.c b/tests/basic/gfapi/glfs_sysrq.c index c843c2a3559..13e06be6df2 100644 --- a/tests/basic/gfapi/glfs_sysrq.c +++ b/tests/basic/gfapi/glfs_sysrq.c @@ -10,52 +10,51 @@ #include <glusterfs/api/glfs.h> int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { - /* cmdline arguments */ - char *host = NULL; - char *volume = NULL; - char *logfile = NULL; - - /* other variables */ - glfs_t *fs = NULL; - int ret = 0; - - if (argc != 4) { - fprintf (stderr, "Usage: %s <host> <volume> <logfile>\n", - argv[0]); - return -1; - } - - host = argv[1]; - volume = argv[2]; - logfile = argv[3]; - - fs = glfs_new (volume); - if (!fs) { - return -1; - } - - ret = glfs_set_logging (fs, logfile, 7); - if (ret < 0) { - return -1; - } - - ret = glfs_set_volfile_server (fs, "tcp", host, 24007); - if (ret < 0) { - return -1; - } - - ret = glfs_init (fs); - if (ret < 0) { - return -1; - } - - /* checking of the results is easier in the script running this test */ - glfs_sysrq (fs, GLFS_SYSRQ_HELP); - glfs_sysrq (fs, GLFS_SYSRQ_STATEDUMP); - - glfs_fini (fs); - - return 0; + /* cmdline arguments */ + char *host = NULL; + char *volume = NULL; + char *logfile = NULL; + + /* other variables */ + glfs_t *fs = NULL; + int ret = 0; + + if (argc != 4) { + fprintf(stderr, "Usage: %s <host> <volume> <logfile>\n", argv[0]); + return -1; + } + + host = argv[1]; + volume = argv[2]; + logfile = argv[3]; + + fs = glfs_new(volume); + if (!fs) { + return -1; + } + + ret = glfs_set_logging(fs, logfile, 7); + if (ret < 0) { + return -1; + } + + ret = glfs_set_volfile_server(fs, "tcp", host, 24007); + if (ret < 0) { + return -1; + } + + ret = glfs_init(fs); + if (ret < 0) { + return -1; + } + + /* checking of the results is easier in the script running this test */ + glfs_sysrq(fs, GLFS_SYSRQ_HELP); + glfs_sysrq(fs, GLFS_SYSRQ_STATEDUMP); + + glfs_fini(fs); + + return 0; } diff --git a/tests/basic/gfapi/glfs_xreaddirplus_r.c b/tests/basic/gfapi/glfs_xreaddirplus_r.c index 17f4d1b1d57..0c4c79123eb 100644 --- a/tests/basic/gfapi/glfs_xreaddirplus_r.c +++ b/tests/basic/gfapi/glfs_xreaddirplus_r.c @@ -6,237 +6,237 @@ #include <glusterfs/api/glfs-handles.h> #include <time.h> -#define VALIDATE_AND_GOTO_LABEL_ON_ERROR(func, ret, label) do { \ - if (ret < 0) { \ - fprintf (stderr, "%s : returned error %d (%s)\n", \ - func, ret, strerror (errno)); \ - goto label; \ - } \ - } while (0) - -#define VALIDATE_BOOL_AND_GOTO_LABEL_ON_ERROR(func, bool_var, ret, label) do { \ - if (!bool_var) { \ - fprintf (stderr, "%s : returned error (%s)\n", \ - func, strerror (errno)); \ - ret = -1; \ - goto label; \ - } \ - } while (0) +#define VALIDATE_AND_GOTO_LABEL_ON_ERROR(func, ret, label) \ + do { \ + if (ret < 0) { \ + fprintf(stderr, "%s : returned error %d (%s)\n", func, ret, \ + strerror(errno)); \ + goto label; \ + } \ + } while (0) + +#define VALIDATE_BOOL_AND_GOTO_LABEL_ON_ERROR(func, bool_var, ret, label) \ + do { \ + if (!bool_var) { \ + fprintf(stderr, "%s : returned error (%s)\n", func, \ + strerror(errno)); \ + ret = -1; \ + goto label; \ + } \ + } while (0) #define MAX_FILES_CREATE 10 -#define MAXPATHNAME 512 +#define MAXPATHNAME 512 void -assimilatetime (struct timespec *ts, struct timespec ts_st, - struct timespec ts_ed) +assimilatetime(struct timespec *ts, struct timespec ts_st, + struct timespec ts_ed) { - if ((ts_ed.tv_nsec - ts_st.tv_nsec) < 0) { - ts->tv_sec += ts_ed.tv_sec - ts_st.tv_sec - 1; - ts->tv_nsec += 1000000000 + ts_ed.tv_nsec - ts_st.tv_nsec; - } else { - ts->tv_sec += ts_ed.tv_sec - ts_st.tv_sec; - ts->tv_nsec += ts_ed.tv_nsec - ts_st.tv_nsec; - } - - if (ts->tv_nsec > 1000000000) { - ts->tv_nsec = ts->tv_nsec - 1000000000; - ts->tv_sec += 1; - } - - return; + if ((ts_ed.tv_nsec - ts_st.tv_nsec) < 0) { + ts->tv_sec += ts_ed.tv_sec - ts_st.tv_sec - 1; + ts->tv_nsec += 1000000000 + ts_ed.tv_nsec - ts_st.tv_nsec; + } else { + ts->tv_sec += ts_ed.tv_sec - ts_st.tv_sec; + ts->tv_nsec += ts_ed.tv_nsec - ts_st.tv_nsec; + } + + if (ts->tv_nsec > 1000000000) { + ts->tv_nsec = ts->tv_nsec - 1000000000; + ts->tv_sec += 1; + } + + return; } /* * Returns '%' difference between ts1 & ts2 */ int -comparetime (struct timespec ts1, struct timespec ts2) +comparetime(struct timespec ts1, struct timespec ts2) { - uint64_t ts1_n, ts2_n; - int pct = 0; + uint64_t ts1_n, ts2_n; + int pct = 0; - ts1_n = (ts1.tv_sec * 1000000000) + ts1.tv_nsec; - ts2_n = (ts2.tv_sec * 1000000000) + ts2.tv_nsec; + ts1_n = (ts1.tv_sec * 1000000000) + ts1.tv_nsec; + ts2_n = (ts2.tv_sec * 1000000000) + ts2.tv_nsec; - pct = ((ts1_n - ts2_n)*100)/ts1_n; + pct = ((ts1_n - ts2_n) * 100) / ts1_n; - return pct; + return pct; } int -old_readdir (glfs_t *fs) +old_readdir(glfs_t *fs) { - struct glfs_object *root = NULL; - struct glfs_fd *fd = NULL; - struct stat *sb = NULL; - char buf[512]; - struct dirent *entry = NULL; - int ret = -1; - struct glfs_object *glhandle = NULL; - - if (!fs) - return -1; - - root = glfs_h_lookupat (fs, NULL, "/", sb, 0); - VALIDATE_BOOL_AND_GOTO_LABEL_ON_ERROR ("glfs_h_lookupat", !!root, ret, out); - - fd = glfs_opendir (fs, "/"); - VALIDATE_BOOL_AND_GOTO_LABEL_ON_ERROR ("glfs_opendir", !!fd, ret, out); - - while (glfs_readdir_r (fd, (struct dirent *)buf, &entry), entry) { - if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) { - glhandle = glfs_h_lookupat (fs, root, "/", sb, 0); - VALIDATE_BOOL_AND_GOTO_LABEL_ON_ERROR ("glfs_h_lookupat", !!glhandle, ret, out); - } + struct glfs_object *root = NULL; + struct glfs_fd *fd = NULL; + struct stat *sb = NULL; + char buf[512]; + struct dirent *entry = NULL; + int ret = -1; + struct glfs_object *glhandle = NULL; + + if (!fs) + return -1; + + root = glfs_h_lookupat(fs, NULL, "/", sb, 0); + VALIDATE_BOOL_AND_GOTO_LABEL_ON_ERROR("glfs_h_lookupat", !!root, ret, out); + + fd = glfs_opendir(fs, "/"); + VALIDATE_BOOL_AND_GOTO_LABEL_ON_ERROR("glfs_opendir", !!fd, ret, out); + + while (glfs_readdir_r(fd, (struct dirent *)buf, &entry), entry) { + if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) { + glhandle = glfs_h_lookupat(fs, root, "/", sb, 0); + VALIDATE_BOOL_AND_GOTO_LABEL_ON_ERROR("glfs_h_lookupat", !!glhandle, + ret, out); } + } - glfs_closedir (fd); + glfs_closedir(fd); - ret = 0; + ret = 0; out: - return ret; + return ret; } int -new_xreaddirplus (glfs_t *fs) +new_xreaddirplus(glfs_t *fs) { - struct glfs_fd *fd = NULL; - struct stat *sb = NULL; - int ret = -1; - uint32_t rflags = (GFAPI_XREADDIRP_STAT | - GFAPI_XREADDIRP_HANDLE); - struct glfs_xreaddirp_stat *xstat = NULL; - struct dirent de; - struct dirent *pde = NULL; - struct glfs_object *glhandle = NULL; - - if (!fs) - return -1; - - fd = glfs_opendir (fs, "/"); - VALIDATE_BOOL_AND_GOTO_LABEL_ON_ERROR ("glfs_opendir", !!fd, ret, out); - - ret = glfs_xreaddirplus_r(fd, rflags, &xstat, &de, &pde); - while (ret > 0 && pde != NULL) { - if (xstat) { - sb = glfs_xreaddirplus_get_stat (xstat); - VALIDATE_BOOL_AND_GOTO_LABEL_ON_ERROR ("glfs_xreaddirplus_get_stat", !!sb, ret, out); - - if (strcmp(de.d_name, ".") && strcmp(de.d_name, "..")) { - glhandle = glfs_xreaddirplus_get_object (xstat); - VALIDATE_BOOL_AND_GOTO_LABEL_ON_ERROR ("glfs_xreaddirplus_get_object", !!glhandle, ret, out); - } - } - - if (xstat) { - glfs_free(xstat); - xstat = NULL; - } + struct glfs_fd *fd = NULL; + struct stat *sb = NULL; + int ret = -1; + uint32_t rflags = (GFAPI_XREADDIRP_STAT | GFAPI_XREADDIRP_HANDLE); + struct glfs_xreaddirp_stat *xstat = NULL; + struct dirent de; + struct dirent *pde = NULL; + struct glfs_object *glhandle = NULL; + + if (!fs) + return -1; + + fd = glfs_opendir(fs, "/"); + VALIDATE_BOOL_AND_GOTO_LABEL_ON_ERROR("glfs_opendir", !!fd, ret, out); + + ret = glfs_xreaddirplus_r(fd, rflags, &xstat, &de, &pde); + while (ret > 0 && pde != NULL) { + if (xstat) { + sb = glfs_xreaddirplus_get_stat(xstat); + VALIDATE_BOOL_AND_GOTO_LABEL_ON_ERROR("glfs_xreaddirplus_get_stat", + !!sb, ret, out); + + if (strcmp(de.d_name, ".") && strcmp(de.d_name, "..")) { + glhandle = glfs_xreaddirplus_get_object(xstat); + VALIDATE_BOOL_AND_GOTO_LABEL_ON_ERROR( + "glfs_xreaddirplus_get_object", !!glhandle, ret, out); + } + } - ret = glfs_xreaddirplus_r(fd, rflags, &xstat, &de, &pde); + if (xstat) { + glfs_free(xstat); + xstat = NULL; + } - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_xreaddirp_r", ret, out); + ret = glfs_xreaddirplus_r(fd, rflags, &xstat, &de, &pde); - } + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_xreaddirp_r", ret, out); + } - if (xstat) - glfs_free(xstat); + if (xstat) + glfs_free(xstat); - ret = 0; + ret = 0; out: - return ret; + return ret; } int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { - int ret = -1; - glfs_t *fs = NULL; - char *volname = NULL; - char *logfile = NULL; - char *hostname = NULL; - char *my_file = "file_"; - char my_file_name[MAXPATHNAME]; - uint32_t flags = O_RDWR|O_SYNC; - struct glfs_fd *fd = NULL; - int i = 0; - int pct = 0; - struct timespec timestamp = {0, 0}, st_timestamp, ed_timestamp; - struct timespec otimestamp = {0, 0}, ost_timestamp, oed_timestamp; - - if (argc != 4) { - fprintf (stderr, "Invalid argument\n"); - return 1; - } + int ret = -1; + glfs_t *fs = NULL; + char *volname = NULL; + char *logfile = NULL; + char *hostname = NULL; + char *my_file = "file_"; + char my_file_name[MAXPATHNAME]; + uint32_t flags = O_RDWR | O_SYNC; + struct glfs_fd *fd = NULL; + int i = 0; + int pct = 0; + struct timespec timestamp = {0, 0}, st_timestamp, ed_timestamp; + struct timespec otimestamp = {0, 0}, ost_timestamp, oed_timestamp; - hostname = argv[1]; - volname = argv[2]; - logfile = argv[3]; + if (argc != 4) { + fprintf(stderr, "Invalid argument\n"); + return 1; + } - fs = glfs_new (volname); - VALIDATE_BOOL_AND_GOTO_LABEL_ON_ERROR ("glfs_new", !!fs, ret, out); + hostname = argv[1]; + volname = argv[2]; + logfile = argv[3]; - ret = glfs_set_volfile_server (fs, "tcp", hostname, 24007); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_set_volfile_server", ret, out); + fs = glfs_new(volname); + VALIDATE_BOOL_AND_GOTO_LABEL_ON_ERROR("glfs_new", !!fs, ret, out); - ret = glfs_set_logging (fs, logfile, 7); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_set_logging", ret, out); + ret = glfs_set_volfile_server(fs, "tcp", hostname, 24007); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_set_volfile_server", ret, out); - ret = glfs_init (fs); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("glfs_init", ret, out); + ret = glfs_set_logging(fs, logfile, 7); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_set_logging", ret, out); - for (i = 0; i < MAX_FILES_CREATE; i++) { - sprintf (my_file_name, "%s%d", my_file, i); + ret = glfs_init(fs); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_init", ret, out); - fd = glfs_creat(fs, my_file_name, flags, 0644); - VALIDATE_BOOL_AND_GOTO_LABEL_ON_ERROR ("glfs_creat", !!fd, ret, out); + for (i = 0; i < MAX_FILES_CREATE; i++) { + sprintf(my_file_name, "%s%d", my_file, i); - glfs_close (fd); - } + fd = glfs_creat(fs, my_file_name, flags, 0644); + VALIDATE_BOOL_AND_GOTO_LABEL_ON_ERROR("glfs_creat", !!fd, ret, out); - /* measure performance using old readdir call and new xreaddirplus call and compare */ - ret = clock_gettime (CLOCK_REALTIME, &ost_timestamp); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("clock_gettime", ret, out); + glfs_close(fd); + } - ret = old_readdir (fs); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("old_readdir", ret, out); + /* measure performance using old readdir call and new xreaddirplus call and + * compare */ + ret = clock_gettime(CLOCK_REALTIME, &ost_timestamp); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("clock_gettime", ret, out); - ret = clock_gettime (CLOCK_REALTIME, &oed_timestamp); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("clock_gettime", ret, out); + ret = old_readdir(fs); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("old_readdir", ret, out); - assimilatetime (&otimestamp, ost_timestamp, oed_timestamp); + ret = clock_gettime(CLOCK_REALTIME, &oed_timestamp); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("clock_gettime", ret, out); - printf ("\tOverall time using readdir:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n", - otimestamp.tv_sec, otimestamp.tv_nsec); + assimilatetime(&otimestamp, ost_timestamp, oed_timestamp); + printf("\tOverall time using readdir:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n", + otimestamp.tv_sec, otimestamp.tv_nsec); - ret = clock_gettime (CLOCK_REALTIME, &st_timestamp); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("clock_gettime", ret, out); + ret = clock_gettime(CLOCK_REALTIME, &st_timestamp); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("clock_gettime", ret, out); - ret = new_xreaddirplus (fs); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("new_xreaddirplus", ret, out); + ret = new_xreaddirplus(fs); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("new_xreaddirplus", ret, out); - ret = clock_gettime (CLOCK_REALTIME, &ed_timestamp); - VALIDATE_AND_GOTO_LABEL_ON_ERROR ("clock_gettime", ret, out); + ret = clock_gettime(CLOCK_REALTIME, &ed_timestamp); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("clock_gettime", ret, out); - assimilatetime (×tamp, st_timestamp, ed_timestamp); + assimilatetime(×tamp, st_timestamp, ed_timestamp); - printf ("\tOverall time using xreaddirplus:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n", - timestamp.tv_sec, timestamp.tv_nsec); + printf("\tOverall time using xreaddirplus:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n", + timestamp.tv_sec, timestamp.tv_nsec); + pct = comparetime(otimestamp, timestamp); + printf("There is improvement by %d%%\n", pct); - pct = comparetime (otimestamp, timestamp); - printf ("There is improvement by %d%%\n", pct); - - ret = 0; + ret = 0; out: - if (fs) { - ret = glfs_fini(fs); - if (ret) - fprintf (stderr, "glfs_fini(fs) returned %d\n", ret); - } + if (fs) { + ret = glfs_fini(fs); + if (ret) + fprintf(stderr, "glfs_fini(fs) returned %d\n", ret); + } - return ret; + return ret; } - - diff --git a/tests/basic/gfapi/glfsxmp-coverage.c b/tests/basic/gfapi/glfsxmp-coverage.c new file mode 100644 index 00000000000..51650023efd --- /dev/null +++ b/tests/basic/gfapi/glfsxmp-coverage.c @@ -0,0 +1,1900 @@ +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <glusterfs/api/glfs.h> +#include <glusterfs/api/glfs-handles.h> +#include <string.h> +#include <time.h> + +#define TEST_STR_LEN 2048 + +int +test_dirops(glfs_t *fs) +{ + glfs_fd_t *fd = NULL; + char buf[2048]; + struct dirent *entry = NULL; + + fd = glfs_opendir(fs, "/"); + if (!fd) { + fprintf(stderr, "/: %s\n", strerror(errno)); + return -1; + } + + fprintf(stderr, "Entries:\n"); + while (glfs_readdir_r(fd, (struct dirent *)buf, &entry), entry) { + fprintf(stderr, "%s: %lu\n", entry->d_name, glfs_telldir(fd)); + } + + /* Should internally call fsyncdir(), hopefully */ + glfs_fsync(fd, NULL, NULL); + + glfs_closedir(fd); + return 0; +} + +int +test_xattr(glfs_t *fs) +{ + char *filename = "/filename2"; + char *linkfile = "/linkfile"; + glfs_fd_t *fd = NULL; + char buf[512]; + char *ptr; + int ret; + + ret = glfs_setxattr(fs, filename, "user.testkey", "testval", 8, 0); + fprintf(stderr, "setxattr(%s): %d (%s)\n", filename, ret, strerror(errno)); + + ret = glfs_setxattr(fs, filename, "user.testkey2", "testval", 8, 0); + fprintf(stderr, "setxattr(%s): %d (%s)\n", filename, ret, strerror(errno)); + + ret = glfs_getxattr(fs, filename, "user.testkey", buf, 512); + fprintf(stderr, "getxattr(%s): %d (%s)\n", filename, ret, strerror(errno)); + if (ret < 0) + return -1; + + ret = glfs_listxattr(fs, filename, buf, 512); + fprintf(stderr, "listxattr(%s): %d (%s)\n", filename, ret, strerror(errno)); + if (ret < 0) + return -1; + + ret = glfs_symlink(fs, "filename", linkfile); + fprintf(stderr, "symlink(%s %s): %s\n", filename, linkfile, + strerror(errno)); + if (ret < 0) + return -1; + + ret = glfs_readlink(fs, linkfile, buf, 512); + fprintf(stderr, "readlink(%s) : %d (%s)\n", filename, ret, strerror(errno)); + if (ret < 0) + return -1; + + ret = glfs_lsetxattr(fs, filename, "user.testkey3", "testval", 8, 0); + fprintf(stderr, "lsetxattr(%s) : %d (%s)\n", linkfile, ret, + strerror(errno)); + if (ret < 0) + return -1; + + ret = glfs_llistxattr(fs, linkfile, buf, 512); + fprintf(stderr, "llistxattr(%s): %d (%s)\n", filename, ret, + strerror(errno)); + if (ret < 0) + return -1; + + ret = glfs_lgetxattr(fs, filename, "user.testkey3", buf, 512); + fprintf(stderr, "lgetxattr(%s): %d (%s)\n", linkfile, ret, strerror(errno)); + if (ret < 0) + return -1; + + for (ptr = buf; ptr < buf + ret; ptr++) { + printf("key=%s\n", ptr); + ptr += strlen(ptr); + } + + ret = glfs_removexattr(fs, filename, "user.testkey2"); + fprintf(stderr, "removexattr(%s): %d (%s)\n", filename, ret, + strerror(errno)); + + fd = glfs_open(fs, filename, O_RDWR); + fprintf(stderr, "open(%s): (%p) %s\n", filename, fd, strerror(errno)); + + ret = glfs_fsetxattr(fd, "user.testkey2", "testval", 8, 0); + fprintf(stderr, "fsetxattr(%s): %d (%s)\n", filename, ret, strerror(errno)); + + ret = glfs_fgetxattr(fd, "user.testkey2", buf, 512); + fprintf(stderr, "fgetxattr(%s): %d (%s)\n", filename, ret, strerror(errno)); + + ret = glfs_flistxattr(fd, buf, 512); + fprintf(stderr, "flistxattr(%s): %d (%s)\n", filename, ret, + strerror(errno)); + if (ret < 0) + return -1; + + for (ptr = buf; ptr < buf + ret; ptr++) { + printf("key=%s\n", ptr); + ptr += strlen(ptr); + } + + ret = glfs_fremovexattr(fd, "user.testkey2"); + fprintf(stderr, "fremovexattr(%s): %d (%s)\n", filename, ret, + strerror(errno)); + + glfs_close(fd); + + return 0; +} + +int +test_chdir(glfs_t *fs) +{ + int ret = -1; + char *dir = "/dir"; + char *topdir = "/topdir"; + char *linkdir = "/linkdir"; + char *linkdir2 = "/linkdir2"; + char *subdir = "./subdir"; + char *respath = NULL; + char pathbuf[4096]; + + ret = glfs_mkdir(fs, topdir, 0755); + fprintf(stderr, "mkdir(%s): %s\n", topdir, strerror(errno)); + if (ret) + return -1; + + ret = glfs_mkdir(fs, dir, 0755); + fprintf(stderr, "mkdir(%s): %s\n", dir, strerror(errno)); + if (ret) + return -1; + + respath = glfs_getcwd(fs, pathbuf, 4096); + fprintf(stdout, "getcwd() = %s\n", respath); + + ret = glfs_symlink(fs, "topdir", linkdir); + if (ret) { + fprintf(stderr, "symlink(%s, %s): %s\n", topdir, linkdir, + strerror(errno)); + return -1; + } + + ret = glfs_chdir(fs, linkdir); + if (ret) { + fprintf(stderr, "chdir(%s): %s\n", linkdir, strerror(errno)); + return -1; + } + + respath = glfs_getcwd(fs, pathbuf, 4096); + fprintf(stdout, "getcwd() = %s\n", respath); + + respath = glfs_realpath(fs, subdir, pathbuf); + if (respath) { + fprintf(stderr, "realpath(%s) worked unexpectedly: %s\n", subdir, + respath); + return -1; + } + + ret = glfs_mkdir(fs, subdir, 0755); + if (ret) { + fprintf(stderr, "mkdir(%s): %s\n", subdir, strerror(errno)); + return -1; + } + + respath = glfs_realpath(fs, subdir, pathbuf); + if (!respath) { + fprintf(stderr, "realpath(%s): %s\n", subdir, strerror(errno)); + } else { + fprintf(stdout, "realpath(%s) = %s\n", subdir, respath); + } + + ret = glfs_chdir(fs, subdir); + if (ret) { + fprintf(stderr, "chdir(%s): %s\n", subdir, strerror(errno)); + return -1; + } + + respath = glfs_getcwd(fs, pathbuf, 4096); + fprintf(stdout, "getcwd() = %s\n", respath); + + respath = glfs_realpath(fs, "/linkdir/subdir", pathbuf); + if (!respath) { + fprintf(stderr, "realpath(/linkdir/subdir): %s\n", strerror(errno)); + } else { + fprintf(stdout, "realpath(/linkdir/subdir) = %s\n", respath); + } + + return 0; +} + +#ifdef DEBUG +static void +peek_stat(struct stat *sb) +{ + printf("Dumping stat information:\n"); + printf("File type: "); + + switch (sb->st_mode & S_IFMT) { + case S_IFBLK: + printf("block device\n"); + break; + case S_IFCHR: + printf("character device\n"); + break; + case S_IFDIR: + printf("directory\n"); + break; + case S_IFIFO: + printf("FIFO/pipe\n"); + break; + case S_IFLNK: + printf("symlink\n"); + break; + case S_IFREG: + printf("regular file\n"); + break; + case S_IFSOCK: + printf("socket\n"); + break; + default: + printf("unknown?\n"); + break; + } + + printf("I-node number: %ld\n", (long)sb->st_ino); + + printf("Mode: %lo (octal)\n", + (unsigned long)sb->st_mode); + + printf("Link count: %ld\n", (long)sb->st_nlink); + printf("Ownership: UID=%ld GID=%ld\n", (long)sb->st_uid, + (long)sb->st_gid); + + printf("Preferred I/O block size: %ld bytes\n", (long)sb->st_blksize); + printf("File size: %lld bytes\n", (long long)sb->st_size); + printf("Blocks allocated: %lld\n", (long long)sb->st_blocks); + + printf("Last status change: %s", ctime(&sb->st_ctime)); + printf("Last file access: %s", ctime(&sb->st_atime)); + printf("Last file modification: %s", ctime(&sb->st_mtime)); + + return; +} + +static void +peek_handle(unsigned char *glid) +{ + int i; + + for (i = 0; i < GFAPI_HANDLE_LENGTH; i++) { + printf(":%02x:", glid[i]); + } + printf("\n"); +} +#else /* DEBUG */ +static void +peek_stat(struct stat *sb) +{ + return; +} + +static void +peek_handle(unsigned char *id) +{ + return; +} +#endif /* DEBUG */ + +glfs_t *fs = NULL; +char *full_parent_name = "/testdir", *parent_name = "testdir"; + +void +test_h_unlink(void) +{ + char *my_dir = "unlinkdir"; + char *my_file = "file.txt"; + char *my_subdir = "dir1"; + struct glfs_object *parent = NULL, *leaf = NULL, *dir = NULL, + *subdir = NULL, *subleaf = NULL; + struct stat sb; + int ret; + + printf("glfs_h_unlink tests: In Progress\n"); + + /* Prepare tests */ + parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (parent == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, NULL, strerror(errno)); + printf("glfs_h_lookupat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + dir = glfs_h_mkdir(fs, parent, my_dir, 0755, &sb); + if (dir == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + my_dir, parent, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + leaf = glfs_h_creat(fs, dir, my_file, O_CREAT, 0644, &sb); + if (leaf == NULL) { + fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n", + my_file, dir, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + subdir = glfs_h_mkdir(fs, dir, my_subdir, 0755, &sb); + if (subdir == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + my_subdir, dir, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + subleaf = glfs_h_creat(fs, subdir, my_file, O_CREAT, 0644, &sb); + if (subleaf == NULL) { + fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n", + my_file, subdir, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + /* unlink non empty directory */ + ret = glfs_h_unlink(fs, dir, my_subdir); + if ((ret && errno != ENOTEMPTY) || (ret == 0)) { + fprintf(stderr, + "glfs_h_unlink: error unlinking %s: it is non empty: %s\n", + my_subdir, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + /* unlink regular file */ + ret = glfs_h_unlink(fs, subdir, my_file); + if (ret) { + fprintf(stderr, "glfs_h_unlink: error unlinking %s: from (%p),%s\n", + my_file, subdir, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + /* unlink directory */ + ret = glfs_h_unlink(fs, dir, my_subdir); + if (ret) { + fprintf(stderr, "glfs_h_unlink: error unlinking %s: from (%p),%s\n", + my_subdir, dir, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + /* unlink regular file */ + ret = glfs_h_unlink(fs, dir, my_file); + if (ret) { + fprintf(stderr, "glfs_h_unlink: error unlinking %s: from (%p),%s\n", + my_file, dir, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + /* unlink non-existent regular file */ + ret = glfs_h_unlink(fs, dir, my_file); + if ((ret && errno != ENOENT) || (ret == 0)) { + fprintf(stderr, + "glfs_h_unlink: error unlinking non-existent %s: invalid errno " + ",%d, %s\n", + my_file, ret, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + /* unlink non-existent directory */ + ret = glfs_h_unlink(fs, dir, my_subdir); + if ((ret && errno != ENOENT) || (ret == 0)) { + fprintf(stderr, + "glfs_h_unlink: error unlinking non-existent %s: invalid " + "errno ,%d, %s\n", + my_subdir, ret, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + /* unlink directory */ + ret = glfs_h_unlink(fs, parent, my_dir); + if (ret) { + fprintf(stderr, "glfs_h_unlink: error unlinking %s: from (%p),%s\n", + my_dir, dir, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + printf("glfs_h_unlink tests: PASSED\n"); + +out: + if (dir) + glfs_h_close(dir); + if (leaf) + glfs_h_close(leaf); + if (subdir) + glfs_h_close(subdir); + if (subleaf) + glfs_h_close(subleaf); + if (parent) + glfs_h_close(parent); + + return; +} + +void +test_h_getsetattrs(void) +{ + char *my_dir = "attrdir"; + char *my_file = "attrfile.txt"; + struct glfs_object *parent = NULL, *leaf = NULL, *dir = NULL; + struct stat sb, retsb; + int ret, valid; + struct timespec timestamp; + + printf("glfs_h_getattrs and setattrs tests: In Progress\n"); + + /* Prepare tests */ + parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (parent == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, NULL, strerror(errno)); + printf("glfs_h_lookupat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + dir = glfs_h_mkdir(fs, parent, my_dir, 0755, &sb); + if (dir == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + my_dir, parent, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + leaf = glfs_h_creat(fs, dir, my_file, O_CREAT, 0644, &sb); + if (leaf == NULL) { + fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n", + my_file, dir, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + ret = glfs_h_getattrs(fs, dir, &retsb); + if (ret != 0) { + fprintf(stderr, "glfs_h_getattrs: error %s: from (%p),%s\n", my_dir, + dir, strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + peek_stat(&retsb); + /* TODO: Compare stat information */ + + retsb.st_mode = 00666; + retsb.st_uid = 1000; + retsb.st_gid = 1001; + ret = clock_gettime(CLOCK_REALTIME, ×tamp); + if (ret != 0) { + fprintf(stderr, "clock_gettime: error %s\n", strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + retsb.st_atim = timestamp; + retsb.st_mtim = timestamp; + valid = GFAPI_SET_ATTR_MODE | GFAPI_SET_ATTR_UID | GFAPI_SET_ATTR_GID | + GFAPI_SET_ATTR_ATIME | GFAPI_SET_ATTR_MTIME; + peek_stat(&retsb); + + ret = glfs_h_setattrs(fs, dir, &retsb, valid); + if (ret != 0) { + fprintf(stderr, "glfs_h_setattrs: error %s: from (%p),%s\n", my_dir, + dir, strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + + memset(&retsb, 0, sizeof(struct stat)); + ret = glfs_h_stat(fs, dir, &retsb); + if (ret != 0) { + fprintf(stderr, "glfs_h_stat: error %s: from (%p),%s\n", my_dir, dir, + strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + peek_stat(&retsb); + + printf("glfs_h_getattrs and setattrs tests: PASSED\n"); +out: + if (parent) + glfs_h_close(parent); + if (leaf) + glfs_h_close(leaf); + if (dir) + glfs_h_close(dir); + + return; +} + +void +test_h_truncate(void) +{ + char *my_dir = "truncatedir"; + char *my_file = "file.txt"; + struct glfs_object *root = NULL, *parent = NULL, *leaf = NULL; + struct stat sb; + glfs_fd_t *fd = NULL; + char buf[32]; + off_t offset = 0; + int ret = 0; + + printf("glfs_h_truncate tests: In Progress\n"); + + /* Prepare tests */ + root = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (root == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, NULL, strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + parent = glfs_h_mkdir(fs, root, my_dir, 0755, &sb); + if (parent == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + my_dir, root, strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + leaf = glfs_h_creat(fs, parent, my_file, O_CREAT, 0644, &sb); + if (leaf == NULL) { + fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n", + my_file, parent, strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + fd = glfs_h_open(fs, leaf, O_RDWR); + if (fd == NULL) { + fprintf(stderr, "glfs_h_open: error on open of %s: %s\n", my_file, + strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + + memcpy(buf, "abcdefghijklmnopqrstuvwxyz012345", 32); + ret = glfs_write(fd, buf, 32, 0); + + /* run tests */ + /* truncate lower */ + offset = 30; + ret = glfs_h_truncate(fs, leaf, offset); + if (ret != 0) { + fprintf(stderr, "glfs_h_truncate: error creating %s: from (%p),%s\n", + my_file, parent, strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + ret = glfs_h_getattrs(fs, leaf, &sb); + if (ret != 0) { + fprintf(stderr, "glfs_h_getattrs: error for %s (%p),%s\n", my_file, + leaf, strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + if (sb.st_size != offset) { + fprintf(stderr, "glfs_h_truncate: post size mismatch\n"); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + + /* truncate higher */ + offset = 32; + ret = glfs_h_truncate(fs, leaf, offset); + if (ret != 0) { + fprintf(stderr, "glfs_h_truncate: error creating %s: from (%p),%s\n", + my_file, parent, strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + ret = glfs_h_getattrs(fs, leaf, &sb); + if (ret != 0) { + fprintf(stderr, "glfs_h_getattrs: error for %s (%p),%s\n", my_file, + leaf, strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + if (sb.st_size != offset) { + fprintf(stderr, "glfs_h_truncate: post size mismatch\n"); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + + /* truncate equal */ + offset = 30; + ret = glfs_h_truncate(fs, leaf, offset); + if (ret != 0) { + fprintf(stderr, "glfs_h_truncate: error creating %s: from (%p),%s\n", + my_file, parent, strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + ret = glfs_h_getattrs(fs, leaf, &sb); + if (ret != 0) { + fprintf(stderr, "glfs_h_getattrs: error for %s (%p),%s\n", my_file, + leaf, strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + if (sb.st_size != offset) { + fprintf(stderr, "glfs_h_truncate: post size mismatch\n"); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + + printf("glfs_h_truncate tests: PASSED\n"); +out: + if (fd) + glfs_close(fd); + if (root) + glfs_h_close(root); + if (parent) + glfs_h_close(parent); + if (leaf) + glfs_h_close(leaf); + + return; +} + +void +test_h_links(void) +{ + char *my_dir = "linkdir"; + char *my_file = "file.txt"; + char *my_symlnk = "slnk.txt"; + char *my_lnk = "lnk.txt"; + char *linksrc_dir = "dir1"; + char *linktgt_dir = "dir2"; + struct glfs_object *root = NULL, *parent = NULL, *leaf = NULL, + *dirsrc = NULL, *dirtgt = NULL, *dleaf = NULL; + struct glfs_object *ln1 = NULL; + struct stat sb; + int ret; + char *buf = NULL; + + printf("glfs_h_link(s) tests: In Progress\n"); + + /* Prepare tests */ + root = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (root == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, NULL, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + parent = glfs_h_mkdir(fs, root, my_dir, 0755, &sb); + if (parent == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + my_dir, root, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + leaf = glfs_h_creat(fs, parent, my_file, O_CREAT, 0644, &sb); + if (leaf == NULL) { + fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n", + my_file, parent, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + dirsrc = glfs_h_mkdir(fs, parent, linksrc_dir, 0755, &sb); + if (dirsrc == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + linksrc_dir, parent, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + dirtgt = glfs_h_mkdir(fs, parent, linktgt_dir, 0755, &sb); + if (dirtgt == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + linktgt_dir, parent, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + dleaf = glfs_h_creat(fs, dirsrc, my_file, O_CREAT, 0644, &sb); + if (dleaf == NULL) { + fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n", + my_file, dirsrc, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + /* run tests */ + /* sym link: /testdir/linkdir/file.txt to ./slnk.txt */ + ln1 = glfs_h_symlink(fs, parent, my_symlnk, "./file.txt", &sb); + if (ln1 == NULL) { + fprintf(stderr, "glfs_h_symlink: error creating %s: from (%p),%s\n", + my_symlnk, parent, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + buf = calloc(1024, sizeof(char)); + if (buf == NULL) { + fprintf(stderr, "Error allocating memory\n"); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + + ret = glfs_h_readlink(fs, ln1, buf, 1024); + if (ret <= 0) { + fprintf(stderr, "glfs_h_readlink: error reading %s: from (%p),%s\n", + my_symlnk, ln1, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + if (!(strncmp(buf, my_symlnk, strlen(my_symlnk)))) { + fprintf(stderr, + "glfs_h_readlink: error mismatch in link name: actual %s: " + "retrieved %s\n", + my_symlnk, buf); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + + /* link: /testdir/linkdir/file.txt to ./lnk.txt */ + ret = glfs_h_link(fs, leaf, parent, my_lnk); + if (ret != 0) { + fprintf(stderr, "glfs_h_link: error creating %s: from (%p),%s\n", + my_lnk, parent, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + /* TODO: Should write content to a file and read from the link */ + + /* link: /testdir/linkdir/dir1/file.txt to ../dir2/slnk.txt */ + ret = glfs_h_link(fs, dleaf, dirtgt, my_lnk); + if (ret != 0) { + fprintf(stderr, "glfs_h_link: error creating %s: from (%p),%s\n", + my_lnk, dirtgt, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + /* TODO: Should write content to a file and read from the link */ + + printf("glfs_h_link(s) tests: PASSED\n"); + +out: + if (root) + glfs_h_close(root); + if (parent) + glfs_h_close(parent); + if (leaf) + glfs_h_close(leaf); + if (dirsrc) + glfs_h_close(dirsrc); + if (dirtgt) + glfs_h_close(dirtgt); + if (dleaf) + glfs_h_close(dleaf); + if (ln1) + glfs_h_close(ln1); + if (buf) + free(buf); + + return; +} + +void +test_h_rename(void) +{ + char *my_dir = "renamedir"; + char *my_file = "file.txt"; + char *src_dir = "dir1"; + char *tgt_dir = "dir2"; + struct glfs_object *root = NULL, *parent = NULL, *leaf = NULL, + *dirsrc = NULL, *dirtgt = NULL, *dleaf = NULL; + struct stat sb; + int ret; + + printf("glfs_h_rename tests: In Progress\n"); + + /* Prepare tests */ + root = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (root == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, NULL, strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + parent = glfs_h_mkdir(fs, root, my_dir, 0755, &sb); + if (parent == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + my_dir, root, strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + leaf = glfs_h_creat(fs, parent, my_file, O_CREAT, 0644, &sb); + if (leaf == NULL) { + fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n", + my_file, parent, strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + dirsrc = glfs_h_mkdir(fs, parent, src_dir, 0755, &sb); + if (dirsrc == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + src_dir, parent, strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + dirtgt = glfs_h_mkdir(fs, parent, tgt_dir, 0755, &sb); + if (dirtgt == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + tgt_dir, parent, strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + dleaf = glfs_h_creat(fs, dirsrc, my_file, O_CREAT, 0644, &sb); + if (dleaf == NULL) { + fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n", + my_file, dirsrc, strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + /* run tests */ + /* Rename file.txt -> file1.txt */ + ret = glfs_h_rename(fs, parent, "file.txt", parent, "file1.txt"); + if (ret != 0) { + fprintf(stderr, "glfs_h_rename: error renaming %s to %s (%s)\n", + "file.txt", "file1.txt", strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + + /* rename dir1/file.txt -> file.txt */ + ret = glfs_h_rename(fs, dirsrc, "file.txt", parent, "file.txt"); + if (ret != 0) { + fprintf(stderr, "glfs_h_rename: error renaming %s/%s to %s (%s)\n", + src_dir, "file.txt", "file.txt", strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + + /* rename file1.txt -> file.txt (exists) */ + ret = glfs_h_rename(fs, parent, "file1.txt", parent, "file.txt"); + if (ret != 0) { + fprintf(stderr, "glfs_h_rename: error renaming %s to %s (%s)\n", + "file.txt", "file.txt", strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + + /* rename dir1 -> dir3 */ + ret = glfs_h_rename(fs, parent, "dir1", parent, "dir3"); + if (ret != 0) { + fprintf(stderr, "glfs_h_rename: error renaming %s to %s (%s)\n", "dir1", + "dir3", strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + + /* rename dir2 ->dir3 (exists) */ + ret = glfs_h_rename(fs, parent, "dir2", parent, "dir3"); + if (ret != 0) { + fprintf(stderr, "glfs_h_rename: error renaming %s to %s (%s)\n", "dir2", + "dir3", strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + + /* rename file.txt -> dir3 (fail) */ + ret = glfs_h_rename(fs, parent, "file.txt", parent, "dir3"); + if (ret == 0) { + fprintf(stderr, "glfs_h_rename: NO error renaming %s to %s (%s)\n", + "file.txt", "dir3", strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + + /* rename dir3 -> file.txt (fail) */ + ret = glfs_h_rename(fs, parent, "dir3", parent, "file.txt"); + if (ret == 0) { + fprintf(stderr, "glfs_h_rename: NO error renaming %s to %s (%s)\n", + "dir3", "file.txt", strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + + printf("glfs_h_rename tests: PASSED\n"); + +out: + if (root) + glfs_h_close(root); + if (parent) + glfs_h_close(parent); + if (leaf) + glfs_h_close(leaf); + if (dirsrc) + glfs_h_close(dirsrc); + if (dirtgt) + glfs_h_close(dirtgt); + if (dleaf) + glfs_h_close(dleaf); + + return; +} + +void +assimilatetime(struct timespec *ts, struct timespec ts_st, + struct timespec ts_ed) +{ + if ((ts_ed.tv_nsec - ts_st.tv_nsec) < 0) { + ts->tv_sec += ts_ed.tv_sec - ts_st.tv_sec - 1; + ts->tv_nsec += 1000000000 + ts_ed.tv_nsec - ts_st.tv_nsec; + } else { + ts->tv_sec += ts_ed.tv_sec - ts_st.tv_sec; + ts->tv_nsec += ts_ed.tv_nsec - ts_st.tv_nsec; + } + + if (ts->tv_nsec > 1000000000) { + ts->tv_nsec = ts->tv_nsec - 1000000000; + ts->tv_sec += 1; + } + + return; +} + +#define MAX_FILES_CREATE 10 +#define MAXPATHNAME 512 +void +test_h_performance(void) +{ + char *my_dir = "perftest", *full_dir_path = "/testdir/perftest"; + char *my_file = "file_", my_file_name[MAXPATHNAME]; + struct glfs_object *parent = NULL, *leaf = NULL, *dir = NULL; + struct stat sb; + int ret, i; + struct glfs_fd *fd; + struct timespec c_ts = {0, 0}, c_ts_st, c_ts_ed; + struct timespec o_ts = {0, 0}, o_ts_st, o_ts_ed; + + printf("glfs_h_performance tests: In Progress\n"); + + /* Prepare tests */ + parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (parent == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, NULL, strerror(errno)); + printf("glfs_h_performance tests: FAILED\n"); + goto out; + } + + dir = glfs_h_mkdir(fs, parent, my_dir, 0755, &sb); + if (dir == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + my_dir, parent, strerror(errno)); + printf("glfs_h_performance tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + /* create performance */ + ret = clock_gettime(CLOCK_REALTIME, &o_ts_st); + if (ret != 0) { + fprintf(stderr, "clock_gettime: error %s\n", strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + + for (i = 0; i < MAX_FILES_CREATE; i++) { + sprintf(my_file_name, "%s%d", my_file, i); + + ret = clock_gettime(CLOCK_REALTIME, &c_ts_st); + if (ret != 0) { + fprintf(stderr, "clock_gettime: error %s\n", strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + + leaf = glfs_h_lookupat(fs, dir, my_file_name, &sb, 0); + if (leaf != NULL) { + fprintf(stderr, "glfs_h_lookup: exists %s\n", my_file_name); + printf("glfs_h_performance tests: FAILED\n"); + goto out; + } + + leaf = glfs_h_creat(fs, dir, my_file_name, O_CREAT, 0644, &sb); + if (leaf == NULL) { + fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n", + my_file, dir, strerror(errno)); + printf("glfs_h_performance tests: FAILED\n"); + goto out; + } + + ret = clock_gettime(CLOCK_REALTIME, &c_ts_ed); + if (ret != 0) { + fprintf(stderr, "clock_gettime: error %s\n", strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + + assimilatetime(&c_ts, c_ts_st, c_ts_ed); + glfs_h_close(leaf); + leaf = NULL; + } + + ret = clock_gettime(CLOCK_REALTIME, &o_ts_ed); + if (ret != 0) { + fprintf(stderr, "clock_gettime: error %s\n", strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + + assimilatetime(&o_ts, o_ts_st, o_ts_ed); + + printf("Creation performance (handle based):\n\t# empty files:%d\n", + MAX_FILES_CREATE); + printf("\tOverall time:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n", o_ts.tv_sec, + o_ts.tv_nsec); + printf("\tcreate call time time:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n", + c_ts.tv_sec, c_ts.tv_nsec); + + /* create using path */ + c_ts.tv_sec = o_ts.tv_sec = 0; + c_ts.tv_nsec = o_ts.tv_nsec = 0; + + sprintf(my_file_name, "%s1", full_dir_path); + ret = glfs_mkdir(fs, my_file_name, 0755); + if (ret != 0) { + fprintf(stderr, "glfs_mkdir: error creating %s: from (%p),%s\n", my_dir, + parent, strerror(errno)); + printf("glfs_h_performance tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + ret = clock_gettime(CLOCK_REALTIME, &o_ts_st); + if (ret != 0) { + fprintf(stderr, "clock_gettime: error %s\n", strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + + for (i = 0; i < MAX_FILES_CREATE; i++) { + sprintf(my_file_name, "%s1/%sn%d", full_dir_path, my_file, i); + + ret = clock_gettime(CLOCK_REALTIME, &c_ts_st); + if (ret != 0) { + fprintf(stderr, "clock_gettime: error %s\n", strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + + ret = glfs_stat(fs, my_file_name, &sb); + if (ret == 0) { + fprintf(stderr, "glfs_stat: exists %s\n", my_file_name); + printf("glfs_h_performance tests: FAILED\n"); + goto out; + } + + fd = glfs_creat(fs, my_file_name, O_CREAT, 0644); + if (fd == NULL) { + fprintf(stderr, "glfs_creat: error creating %s: from (%p),%s\n", + my_file, dir, strerror(errno)); + printf("glfs_h_performance tests: FAILED\n"); + goto out; + } + + ret = clock_gettime(CLOCK_REALTIME, &c_ts_ed); + if (ret != 0) { + fprintf(stderr, "clock_gettime: error %s\n", strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + + assimilatetime(&c_ts, c_ts_st, c_ts_ed); + glfs_close(fd); + } + + ret = clock_gettime(CLOCK_REALTIME, &o_ts_ed); + if (ret != 0) { + fprintf(stderr, "clock_gettime: error %s\n", strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + + assimilatetime(&o_ts, o_ts_st, o_ts_ed); + + printf("Creation performance (path based):\n\t# empty files:%d\n", + MAX_FILES_CREATE); + printf("\tOverall time:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n", o_ts.tv_sec, + o_ts.tv_nsec); + printf("\tcreate call time time:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n", + c_ts.tv_sec, c_ts.tv_nsec); +out: + return; +} + +int +test_handleops(int argc, char *argv[]) +{ + int ret = 0; + glfs_fd_t *fd = NULL; + struct stat sb = { + 0, + }; + struct glfs_object *root = NULL, *parent = NULL, *leaf = NULL, *tmp = NULL; + char readbuf[32], writebuf[32]; + unsigned char leaf_handle[GFAPI_HANDLE_LENGTH]; + + char *full_leaf_name = "/testdir/testfile.txt", *leaf_name = "testfile.txt", + *relative_leaf_name = "testdir/testfile.txt"; + char *leaf_name1 = "testfile1.txt"; + char *full_newparent_name = "/testdir/dir1", *newparent_name = "dir1"; + char *full_newnod_name = "/testdir/nod1", *newnod_name = "nod1"; + + /* Initialize test area */ + ret = glfs_mkdir(fs, full_parent_name, 0755); + if (ret != 0 && errno != EEXIST) { + fprintf(stderr, "%s: (%p) %s\n", full_parent_name, fd, strerror(errno)); + printf("Test initialization failed on volume %s\n", argv[1]); + goto out; + } else if (ret != 0) { + printf("Found test directory %s to be existing\n", full_parent_name); + printf("Cleanup test directory and restart tests\n"); + goto out; + } + + fd = glfs_creat(fs, full_leaf_name, O_CREAT, 0644); + if (fd == NULL) { + fprintf(stderr, "%s: (%p) %s\n", full_leaf_name, fd, strerror(errno)); + printf("Test initialization failed on volume %s\n", argv[1]); + goto out; + } + glfs_close(fd); + + printf("Initialized the test area, within volume %s\n", argv[1]); + + /* Handle based APIs test area */ + + /* glfs_lookupat test */ + printf("glfs_h_lookupat tests: In Progress\n"); + /* start at root of the volume */ + root = glfs_h_lookupat(fs, NULL, "/", &sb, 0); + if (root == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", "/", + NULL, strerror(errno)); + printf("glfs_h_lookupat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + /* lookup a parent within root */ + parent = glfs_h_lookupat(fs, root, parent_name, &sb, 0); + if (parent == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + parent_name, root, strerror(errno)); + printf("glfs_h_lookupat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + /* lookup a leaf/child within the parent */ + leaf = glfs_h_lookupat(fs, parent, leaf_name, &sb, 0); + if (leaf == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + leaf_name, parent, strerror(errno)); + printf("glfs_h_lookupat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + /* reset */ + glfs_h_close(root); + root = NULL; + glfs_h_close(leaf); + leaf = NULL; + glfs_h_close(parent); + parent = NULL; + + /* check absolute paths */ + root = glfs_h_lookupat(fs, NULL, "/", &sb, 0); + if (root == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", "/", + NULL, strerror(errno)); + printf("glfs_h_lookupat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (parent == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, root, strerror(errno)); + printf("glfs_h_lookupat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + leaf = glfs_h_lookupat(fs, NULL, full_leaf_name, &sb, 0); + if (leaf == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_leaf_name, parent, strerror(errno)); + printf("glfs_h_lookupat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + /* reset */ + glfs_h_close(leaf); + leaf = NULL; + + /* check multiple component paths */ + leaf = glfs_h_lookupat(fs, root, relative_leaf_name, &sb, 0); + if (leaf == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + relative_leaf_name, parent, strerror(errno)); + goto out; + } + peek_stat(&sb); + + /* reset */ + glfs_h_close(root); + root = NULL; + glfs_h_close(parent); + parent = NULL; + + /* check symlinks in path */ + + /* TODO: -ve test cases */ + /* parent invalid + * path invalid + * path does not exist after some components + * no parent, but relative path + * parent and full path? -ve? + */ + + printf("glfs_h_lookupat tests: PASSED\n"); + + /* glfs_openat test */ + printf("glfs_h_open tests: In Progress\n"); + fd = glfs_h_open(fs, leaf, O_RDWR); + if (fd == NULL) { + fprintf(stderr, "glfs_h_open: error on open of %s: %s\n", + full_leaf_name, strerror(errno)); + printf("glfs_h_open tests: FAILED\n"); + goto out; + } + + /* test read/write based on fd */ + memcpy(writebuf, "abcdefghijklmnopqrstuvwxyz012345", 32); + ret = glfs_write(fd, writebuf, 32, 0); + + glfs_lseek(fd, 10, SEEK_SET); + + ret = glfs_read(fd, readbuf, 32, 0); + if (memcmp(readbuf, writebuf, 32)) { + printf("Failed to read what I wrote: %s %s\n", readbuf, writebuf); + glfs_close(fd); + printf("glfs_h_open tests: FAILED\n"); + goto out; + } + + glfs_h_close(leaf); + leaf = NULL; + glfs_close(fd); + + printf("glfs_h_open tests: PASSED\n"); + + /* Create tests */ + printf("glfs_h_creat tests: In Progress\n"); + parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (parent == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, root, strerror(errno)); + printf("glfs_h_creat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + leaf = glfs_h_creat(fs, parent, leaf_name1, O_CREAT, 0644, &sb); + if (leaf == NULL) { + fprintf(stderr, "glfs_h_creat: error on create of %s: from (%p),%s\n", + leaf_name1, parent, strerror(errno)); + printf("glfs_h_creat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + glfs_h_close(leaf); + leaf = NULL; + + leaf = glfs_h_creat(fs, parent, leaf_name1, O_CREAT | O_EXCL, 0644, &sb); + if (leaf != NULL || errno != EEXIST) { + fprintf(stderr, + "glfs_h_creat: existing file, leaf = (%p), errno = %s\n", leaf, + strerror(errno)); + printf("glfs_h_creat tests: FAILED\n"); + if (leaf != NULL) { + glfs_h_close(leaf); + leaf = NULL; + } + } + + tmp = glfs_h_creat(fs, root, parent_name, O_CREAT, 0644, &sb); + if (tmp != NULL || !(errno == EISDIR || errno == EINVAL)) { + fprintf(stderr, "glfs_h_creat: dir create, tmp = (%p), errno = %s\n", + leaf, strerror(errno)); + printf("glfs_h_creat tests: FAILED\n"); + if (tmp != NULL) { + glfs_h_close(tmp); + tmp = NULL; + } + } + + /* TODO: Other combinations and -ve cases as applicable */ + printf("glfs_h_creat tests: PASSED\n"); + + /* extract handle and create from handle test */ + printf( + "glfs_h_extract_handle and glfs_h_create_from_handle tests: In " + "Progress\n"); + /* TODO: Change the lookup to create below for a GIFD recovery failure, + * that needs to be fixed */ + leaf = glfs_h_lookupat(fs, parent, leaf_name1, &sb, 0); + if (leaf == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + leaf_name1, parent, strerror(errno)); + printf("glfs_h_extract_handle tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + ret = glfs_h_extract_handle(leaf, leaf_handle, GFAPI_HANDLE_LENGTH); + if (ret < 0) { + fprintf(stderr, + "glfs_h_extract_handle: error extracting handle of %s: %s\n", + full_leaf_name, strerror(errno)); + printf("glfs_h_extract_handle tests: FAILED\n"); + goto out; + } + peek_handle(leaf_handle); + + glfs_h_close(leaf); + leaf = NULL; + + leaf = glfs_h_create_from_handle(fs, leaf_handle, GFAPI_HANDLE_LENGTH, &sb); + if (leaf == NULL) { + fprintf( + stderr, + "glfs_h_create_from_handle: error on create of %s: from (%p),%s\n", + leaf_name1, leaf_handle, strerror(errno)); + printf("glfs_h_create_from_handle tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + fd = glfs_h_open(fs, leaf, O_RDWR); + if (fd == NULL) { + fprintf(stderr, "glfs_h_open: error on open of %s: %s\n", + full_leaf_name, strerror(errno)); + printf("glfs_h_create_from_handle tests: FAILED\n"); + goto out; + } + + /* test read/write based on fd */ + memcpy(writebuf, "abcdefghijklmnopqrstuvwxyz012345", 32); + ret = glfs_write(fd, writebuf, 32, 0); + + glfs_lseek(fd, 0, SEEK_SET); + + ret = glfs_read(fd, readbuf, 32, 0); + if (memcmp(readbuf, writebuf, 32)) { + printf("Failed to read what I wrote: %s %s\n", writebuf, writebuf); + printf("glfs_h_create_from_handle tests: FAILED\n"); + glfs_close(fd); + goto out; + } + + glfs_close(fd); + glfs_h_close(leaf); + leaf = NULL; + glfs_h_close(parent); + parent = NULL; + + printf( + "glfs_h_extract_handle and glfs_h_create_from_handle tests: PASSED\n"); + + /* Mkdir tests */ + printf("glfs_h_mkdir tests: In Progress\n"); + + ret = glfs_rmdir(fs, full_newparent_name); + if (ret && errno != ENOENT) { + fprintf(stderr, "glfs_rmdir: Failed for %s: %s\n", full_newparent_name, + strerror(errno)); + printf("glfs_h_mkdir tests: FAILED\n"); + goto out; + } + + parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (parent == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, root, strerror(errno)); + printf("glfs_h_mkdir tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + leaf = glfs_h_mkdir(fs, parent, newparent_name, 0755, &sb); + if (leaf == NULL) { + fprintf(stderr, "glfs_h_mkdir: error on mkdir of %s: from (%p),%s\n", + newparent_name, parent, strerror(errno)); + printf("glfs_h_mkdir tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + glfs_h_close(leaf); + leaf = NULL; + + leaf = glfs_h_mkdir(fs, parent, newparent_name, 0755, &sb); + if (leaf != NULL || errno != EEXIST) { + fprintf(stderr, + "glfs_h_mkdir: existing directory, leaf = (%p), errno = %s\n", + leaf, strerror(errno)); + printf("glfs_h_mkdir tests: FAILED\n"); + if (leaf != NULL) { + glfs_h_close(leaf); + leaf = NULL; + } + } + + glfs_h_close(parent); + parent = NULL; + + printf("glfs_h_mkdir tests: PASSED\n"); + + /* Mknod tests */ + printf("glfs_h_mknod tests: In Progress\n"); + ret = glfs_unlink(fs, full_newnod_name); + if (ret && errno != ENOENT) { + fprintf(stderr, "glfs_unlink: Failed for %s: %s\n", full_newnod_name, + strerror(errno)); + printf("glfs_h_mknod tests: FAILED\n"); + goto out; + } + + parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (parent == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, root, strerror(errno)); + printf("glfs_h_mknod tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + leaf = glfs_h_mknod(fs, parent, newnod_name, S_IFIFO, 0, &sb); + if (leaf == NULL) { + fprintf(stderr, "glfs_h_mkdir: error on mkdir of %s: from (%p),%s\n", + newnod_name, parent, strerror(errno)); + printf("glfs_h_mknod tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + /* TODO: create op on a FIFO node hangs, need to check and fix + tmp = glfs_h_creat (fs, parent, newnod_name, O_CREAT, 0644, &sb); + if (tmp != NULL || errno != EINVAL) { + fprintf (stderr, "glfs_h_creat: node create, tmp = (%p), errno = + %s\n", tmp, strerror (errno)); printf ("glfs_h_creat/mknod tests: + FAILED\n"); if (tmp != NULL) { glfs_h_close(tmp); tmp = NULL; + } + } */ + + glfs_h_close(leaf); + leaf = NULL; + + leaf = glfs_h_mknod(fs, parent, newnod_name, 0644, 0, &sb); + if (leaf != NULL || errno != EEXIST) { + fprintf(stderr, + "glfs_h_mknod: existing node, leaf = (%p), errno = %s\n", leaf, + strerror(errno)); + printf("glfs_h_mknod tests: FAILED\n"); + if (leaf != NULL) { + glfs_h_close(leaf); + leaf = NULL; + } + } + + glfs_h_close(parent); + parent = NULL; + + printf("glfs_h_mknod tests: PASSED\n"); + + /* unlink tests */ + test_h_unlink(); + + /* TODO: opendir tests */ + + /* getattr tests */ + test_h_getsetattrs(); + + /* TODO: setattr tests */ + + /* truncate tests */ + test_h_truncate(); + + /* link tests */ + test_h_links(); + + /* rename tests */ + test_h_rename(); + + /* performance tests */ + test_h_performance(); + + /* END: New APIs test area */ + +out: + /* Cleanup glfs handles */ + if (root) + glfs_h_close(root); + if (parent) + glfs_h_close(parent); + if (leaf) + glfs_h_close(leaf); + + return ret; +} + +int +test_write_apis(glfs_t *fs) +{ + /* Add more content here */ + /* Some apis we can get are */ + /* + 0. glfs_set_xlator_option() + + Read/Write combinations: + . glfs_{p,}readv/{p,}writev + . glfs_pread/pwrite + + tests/basic/gfapi/gfapi-async-calls-test.c + . glfs_read_async/write_async + . glfs_pread_async/pwrite_async + . glfs_readv_async/writev_async + . glfs_preadv_async/pwritev_async + + . ftruncate/ftruncate_async + . fsync/fsync_async + . fdatasync/fdatasync_async + + */ + + glfs_fd_t *fd = NULL; + char *filename = "/filename2"; + int flags = O_RDWR; + char *buf = "some bytes!"; + char writestr[TEST_STR_LEN]; + struct iovec iov = {&writestr, TEST_STR_LEN}; + int ret, i; + + for (i = 0; i < TEST_STR_LEN; i++) + writestr[i] = 0x11; + + fd = glfs_open(fs, filename, flags); + if (!fd) + fprintf(stderr, "open(%s): (%p) %s\n", filename, fd, strerror(errno)); + + ret = glfs_writev(fd, &iov, 1, flags); + if (ret < 0) { + fprintf(stderr, "writev(%s): %d (%s)\n", filename, ret, + strerror(errno)); + } + + ret = glfs_pwrite(fd, buf, 10, 4, flags, NULL, NULL); + if (ret < 0) { + fprintf(stderr, "pwrite(%s): %d (%s)\n", filename, ret, + strerror(errno)); + } + + ret = glfs_pwritev(fd, &iov, 1, 4, flags); + if (ret < 0) { + fprintf(stderr, "pwritev(%s): %d (%s)\n", filename, ret, + strerror(errno)); + } + + ret = glfs_fsync(fd, NULL, NULL); + if (ret < 0) { + fprintf(stderr, "fsync(%s): %d (%s)\n", filename, ret, strerror(errno)); + } + + glfs_close(fd); + + return 0; +} + +int +test_metadata_ops(glfs_t *fs, glfs_t *fs2) +{ + glfs_fd_t *fd = NULL; + glfs_fd_t *fd2 = NULL; + struct stat sb = { + 0, + }; + struct glfs_stat gsb = { + 0, + }; + struct statvfs sfs; + char readbuf[32]; + char writebuf[11] = "helloworld"; + + char *filename = "/filename2"; + int ret; + + ret = glfs_lstat(fs, filename, &sb); + fprintf(stderr, "lstat(%s): (%d) %s\n", filename, ret, strerror(errno)); + + fd = glfs_creat(fs, filename, O_RDWR, 0644); + if (!fd) + fprintf(stderr, "creat(%s): (%p) %s\n", filename, fd, strerror(errno)); + + fd2 = glfs_open(fs2, filename, O_RDWR); + if (!fd2) + fprintf(stderr, "open(%s): (%p) %s\n", filename, fd, strerror(errno)); + + ret = glfs_lstat(fs, filename, &sb); + if (ret) + fprintf(stderr, "lstat(%s): (%d) %s\n", filename, ret, strerror(errno)); + + ret = glfs_write(fd, writebuf, 11, 0); + if (ret < 0) { + fprintf(stderr, "writev(%s): %d (%s)\n", filename, ret, + strerror(errno)); + } + + glfs_fsync(fd, NULL, NULL); + + glfs_lseek(fd2, 5, SEEK_SET); + + ret = glfs_read(fd2, readbuf, 32, 0); + + printf("read %d, %s", ret, readbuf); + + /* get stat */ + ret = glfs_fstat(fd2, &sb); + if (ret) + fprintf(stderr, "fstat(%s): %d (%s)\n", filename, ret, strerror(errno)); + + ret = glfs_access(fs, filename, R_OK); + if (ret) + fprintf(stderr, "access(%s): %d (%s)\n", filename, ret, + strerror(errno)); + + ret = glfs_fallocate(fd2, 1024, 1024, 1024); + if (ret) + fprintf(stderr, "fallocate(%s): %d (%s)\n", filename, ret, + strerror(errno)); + + ret = glfs_discard(fd2, 1024, 512); + if (ret) + fprintf(stderr, "discard(%s): %d (%s)\n", filename, ret, + strerror(errno)); + + ret = glfs_zerofill(fd2, 2048, 1024); + if (ret) + fprintf(stderr, "zerofill(%s): %d (%s)\n", filename, ret, + strerror(errno)); + + /* set stat */ + /* TODO: got some errors, need to fix */ + ret = glfs_fsetattr(fd2, &gsb); + + glfs_close(fd); + glfs_close(fd2); + + filename = "/filename3"; + ret = glfs_mknod(fs, filename, S_IFIFO, 0); + if (ret) + fprintf(stderr, "%s: (%d) %s\n", filename, ret, strerror(errno)); + + ret = glfs_lstat(fs, filename, &sb); + if (ret) + fprintf(stderr, "%s: (%d) %s\n", filename, ret, strerror(errno)); + + ret = glfs_rename(fs, filename, "/filename4"); + if (ret) + fprintf(stderr, "rename(%s): (%d) %s\n", filename, ret, + strerror(errno)); + + ret = glfs_unlink(fs, "/filename4"); + if (ret) + fprintf(stderr, "unlink(%s): (%d) %s\n", "/filename4", ret, + strerror(errno)); + + filename = "/dirname2"; + ret = glfs_mkdir(fs, filename, 0); + if (ret) + fprintf(stderr, "%s: (%d) %s\n", filename, ret, strerror(errno)); + + ret = glfs_lstat(fs, filename, &sb); + if (ret) + fprintf(stderr, "lstat(%s): (%d) %s\n", filename, ret, strerror(errno)); + + ret = glfs_rmdir(fs, filename); + if (ret) + fprintf(stderr, "rmdir(%s): (%d) %s\n", filename, ret, strerror(errno)); +} +int +main(int argc, char *argv[]) +{ + glfs_t *fs2 = NULL; + int ret = 0; + glfs_fd_t *fd = NULL; + glfs_fd_t *fd2 = NULL; + struct stat sb = { + 0, + }; + struct glfs_stat gsb = { + 0, + }; + struct statvfs sfs; + char readbuf[32]; + char writebuf[32]; + char volumeid[64]; + + char *filename = "/filename2"; + + if ((argc < 2) || (argc > 3)) { + printf("Usage:\n\t%s <volname> <hostname>\n\t%s <volfile-path>", + argv[0], argv[0]); + return -1; + } + + if (argc == 2) { + /* Generally glfs_new() requires volume name as an argument */ + fs = glfs_new("test-only"); + if (!fs) { + fprintf(stderr, "glfs_new: returned NULL\n"); + return 1; + } + ret = glfs_set_volfile(fs, argv[1]); + if (ret) + fprintf(stderr, "glfs_set_volfile failed\n"); + } else { + fs = glfs_new(argv[1]); + if (!fs) { + fprintf(stderr, "glfs_new: returned NULL\n"); + return 1; + } + // ret = glfs_set_volfile_server (fs, "unix", "/tmp/gluster.sock", 0); + ret = glfs_set_volfile_server(fs, "tcp", argv[2], 24007); + if (ret) + fprintf(stderr, "glfs_set_volfile_server failed\n"); + } + + /* Change this to relevant file when running locally */ + ret = glfs_set_logging(fs, "/dev/stderr", 5); + if (ret) + fprintf(stderr, "glfs_set_logging failed\n"); + + ret = glfs_init(fs); + if (ret) + fprintf(stderr, "glfs_init: returned %d\n", ret); + + if (ret) + goto out; + + /* no major use for getting the volume id in this test, done for coverage */ + ret = glfs_get_volumeid(fs, volumeid, 64); + if (ret) { + fprintf(stderr, "glfs_get_volumeid: returned %d\n", ret); + } + + sleep(2); + + if (argc == 2) { + /* Generally glfs_new() requires volume name as an argument */ + fs2 = glfs_new("test_only_volume"); + if (!fs2) { + fprintf(stderr, "glfs_new(fs2): returned NULL\n"); + return 1; + } + ret = glfs_set_volfile(fs2, argv[1]); + if (ret) + fprintf(stderr, "glfs_set_volfile failed(fs2)\n"); + } else { + fs2 = glfs_new(argv[1]); + if (!fs2) { + fprintf(stderr, "glfs_new(fs2): returned NULL\n"); + return 1; + } + ret = glfs_set_volfile_server(fs2, "tcp", argv[2], 24007); + if (ret) + fprintf(stderr, "glfs_set_volfile_server failed(fs2)\n"); + } + + ret = glfs_set_statedump_path(fs2, "/tmp"); + if (ret) { + fprintf(stderr, "glfs_set_statedump_path: %s\n", strerror(errno)); + } + + ret = glfs_init(fs2); + if (ret) + fprintf(stderr, "glfs_init: returned %d\n", ret); + + test_metadata_ops(fs, fs2); + + test_dirops(fs); + + test_xattr(fs); + + test_chdir(fs); + + test_handleops(argc, argv); + // done + + /* Test some extra apis */ + test_write_apis(fs); + + glfs_statvfs(fs, "/", &sfs); + + glfs_unset_volfile_server(fs, "tcp", argv[2], 24007); + + glfs_fini(fs); + glfs_fini(fs2); + + ret = 0; +out: + return ret; +} diff --git a/tests/basic/gfapi/glfsxmp.t b/tests/basic/gfapi/glfsxmp.t new file mode 100644 index 00000000000..b3e6645c0f5 --- /dev/null +++ b/tests/basic/gfapi/glfsxmp.t @@ -0,0 +1,30 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup + +TEST glusterd + +TEST $CLI volume create $V0 replica 3 $H0:$B0/brick{0,1,2} +EXPECT 'Created' volinfo_field $V0 'Status' + +TEST $CLI volume start $V0 +EXPECT 'Started' volinfo_field $V0 'Status' + +$CLI system getspec $V0 > fubar.vol + +TEST cp $(dirname $0)/glfsxmp-coverage.c ./glfsxmp.c +TEST build_tester ./glfsxmp.c -lgfapi +TEST ./glfsxmp $V0 $H0 + +TEST ./glfsxmp fubar.vol + +TEST cleanup_tester ./glfsxmp +TEST rm ./glfsxmp.c + +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 + +cleanup diff --git a/tests/basic/gfapi/libgfapi-fini-hang.c b/tests/basic/gfapi/libgfapi-fini-hang.c index e192751f295..37800e3188b 100644 --- a/tests/basic/gfapi/libgfapi-fini-hang.c +++ b/tests/basic/gfapi/libgfapi-fini-hang.c @@ -8,56 +8,55 @@ #include <glusterfs/api/glfs.h> #include <glusterfs/api/glfs-handles.h> -#define LOG_ERR(func, ret) do { \ - if (ret != 0) { \ - fprintf (stderr, "%s : returned error %d\n", func, ret); \ - exit(1); \ - } else { \ - fprintf (stderr, "%s : returned %d\n", func, ret); \ - } \ -} while (0) +#define LOG_ERR(func, ret) \ + do { \ + if (ret != 0) { \ + fprintf(stderr, "%s : returned error %d\n", func, ret); \ + exit(1); \ + } else { \ + fprintf(stderr, "%s : returned %d\n", func, ret); \ + } \ + } while (0) int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { - glfs_t *fs = NULL; - int ret = 0, i; - glfs_fd_t *fd = NULL; - char readbuf[32]; - char *logname = NULL; - char *hostname = NULL; - char *volname = NULL; - - fprintf (stderr, "Starting libgfapi_fini\n"); - - if (argc < 4) { - fprintf (stderr, "Invalid argument\n"); - exit(1); - } - - hostname = argv[1]; - volname = argv[2]; - logname = argv[3]; - - fs = glfs_new (volname); - if (!fs) { - fprintf (stderr, "glfs_new: returned NULL\n"); - exit(1); - } - - ret = glfs_set_volfile_server (fs, "tcp", hostname, 0); - LOG_ERR("glfs_set_volfile_server", ret); - - ret = glfs_set_logging (fs, logname, 7); - LOG_ERR("glfs_set_logging", ret); - - /* Do not call glfs_init. - * glfs_fini() shouldn't hang in that case*/ - ret = glfs_fini(fs); - LOG_ERR("glfs_fini", ret); - fprintf (stderr, "End of libgfapi_fini\n"); - - exit(0); + glfs_t *fs = NULL; + int ret = 0, i; + glfs_fd_t *fd = NULL; + char readbuf[32]; + char *logname = NULL; + char *hostname = NULL; + char *volname = NULL; + + fprintf(stderr, "Starting libgfapi_fini\n"); + + if (argc < 4) { + fprintf(stderr, "Invalid argument\n"); + exit(1); + } + + hostname = argv[1]; + volname = argv[2]; + logname = argv[3]; + + fs = glfs_new(volname); + if (!fs) { + fprintf(stderr, "glfs_new: returned NULL\n"); + exit(1); + } + + ret = glfs_set_volfile_server(fs, "tcp", hostname, 0); + LOG_ERR("glfs_set_volfile_server", ret); + + ret = glfs_set_logging(fs, logname, 7); + LOG_ERR("glfs_set_logging", ret); + + /* Do not call glfs_init. + * glfs_fini() shouldn't hang in that case*/ + ret = glfs_fini(fs); + LOG_ERR("glfs_fini", ret); + fprintf(stderr, "End of libgfapi_fini\n"); + + exit(0); } - - 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; +} diff --git a/tests/basic/gfapi/mandatory-lock-optimal.t b/tests/basic/gfapi/mandatory-lock-optimal.t new file mode 100644 index 00000000000..27062e1f6c2 --- /dev/null +++ b/tests/basic/gfapi/mandatory-lock-optimal.t @@ -0,0 +1,38 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup + +TEST glusterd + +# Create and start the volume +TEST $CLI volume create $V0 $H0:$B0/${V0}1 +TEST $CLI volume start $V0 + +logdir=`gluster --print-logdir` + +# Switch off performance translators +TEST $CLI volume set $V0 performance.open-behind off +TEST $CLI volume set $V0 performance.write-behind off +TEST $CLI volume set $V0 performance.quick-read off +TEST $CLI volume set $V0 performance.io-cache off +TEST $CLI volume set $V0 performance.read-ahead off +TEST $CLI volume set $V0 performance.readdir-ahead off + +# Enable optimal mandatory-locking mode and restart the volume +TEST $CLI volume set $V0 locks.mandatory-locking optimal +TEST $CLI volume stop $V0 +TEST $CLI volume start $V0 + +# Compile and run the test program +TEST build_tester $(dirname $0)/mandatory-lock-optimal.c -lgfapi +TEST ./$(dirname $0)/mandatory-lock-optimal $H0 $V0 $logdir + +# Cleanup the environment +cleanup_tester $(dirname $0)/mandatory-lock-optimal +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 + +cleanup diff --git a/tests/basic/gfapi/protocol-client-ssl.vol.in b/tests/basic/gfapi/protocol-client-ssl.vol.in new file mode 100644 index 00000000000..cdc0c9d0671 --- /dev/null +++ b/tests/basic/gfapi/protocol-client-ssl.vol.in @@ -0,0 +1,15 @@ +# +# This .vol file expects that there is +# +# 1. GlusterD listening on @@HOSTNAME@@ +# 2. a volume that provides a brick on @@BRICKPATH@@ +# 3. the volume with the brick has been started +# +volume test + type protocol/client + option remote-host @@HOSTNAME@@ + option remote-subvolume @@BRICKPATH@@ + option transport-type socket + option transport.socket.ssl-enabled @@SSL@@ +end-volume + diff --git a/tests/basic/gfapi/seek.c b/tests/basic/gfapi/seek.c index fb2f6361bf3..85ea9b88141 100644 --- a/tests/basic/gfapi/seek.c +++ b/tests/basic/gfapi/seek.c @@ -18,80 +18,82 @@ #include <glusterfs/api/glfs-handles.h> int -main (int argc, char **argv) +main(int argc, char **argv) { - glfs_t *fs = NULL; - int ret = 0; - glfs_fd_t *fd = NULL; - char *filename = NULL; - char *volname = NULL; - char *hostname = NULL; - struct stat st = { 0, }; - off_t hole_start = 0; - off_t hole_end = 0; - - if (argc != 4) { - fprintf (stderr, "Invalid argument, use %s <hostname> <vol> <file>\n", - argv[0]); - exit (1); + glfs_t *fs = NULL; + int ret = 0; + glfs_fd_t *fd = NULL; + char *filename = NULL; + char *volname = NULL; + char *hostname = NULL; + struct stat st = { + 0, + }; + off_t hole_start = 0; + off_t hole_end = 0; + + if (argc != 4) { + fprintf(stderr, "Invalid argument, use %s <hostname> <vol> <file>\n", + argv[0]); + exit(1); + } + + hostname = argv[1]; + volname = argv[2]; + filename = argv[3]; + + fs = glfs_new(volname); + if (!fs) { + perror("glfs_new() returned NULL"); + return 1; + } + + if (glfs_set_volfile_server(fs, "tcp", hostname, 24007)) { + perror("glfs_set_volfile_server"); + return 1; + } + + if (glfs_init(fs)) { + perror("glfs_init"); + return 1; + } + + fd = glfs_open(fs, filename, O_RDONLY); + if (fd <= 0) { + perror("glfs_open"); + return 1; + } + + if (glfs_fstat(fd, &st)) { + perror("glfs_fstat"); + return 1; + } + + while (hole_end < st.st_size) { + hole_start = glfs_lseek(fd, hole_end, SEEK_HOLE); + if (hole_start == -1 && errno == ENXIO) + /* no more holes */ + break; + if (hole_start == -1) { + perror("no more holes"); + break; } - hostname = argv[1]; - volname = argv[2]; - filename = argv[3]; - - fs = glfs_new (volname); - if (!fs) { - perror ("glfs_new() returned NULL"); - return 1; - } - - if (glfs_set_volfile_server (fs, "tcp", hostname, 24007)) { - perror ("glfs_set_volfile_server"); - return 1; + hole_end = glfs_lseek(fd, hole_start, SEEK_DATA); + if (hole_end == -1 && errno == ENXIO) { + /* no more data */ + break; } - if (glfs_init (fs)) { - perror ("glfs_init"); - return 1; - } + printf("HOLE found: %ld - %ld%s\n", hole_start, hole_end, + (hole_end == st.st_size) ? " (EOF)" : ""); + } - fd = glfs_open (fs, filename, O_RDONLY); - if (fd <= 0) { - perror ("glfs_open"); - return 1; - } + glfs_close(fd); - if (glfs_fstat (fd, &st)) { - perror ("glfs_fstat"); - return 1; - } - - while (hole_end < st.st_size) { - hole_start = glfs_lseek (fd, hole_end, SEEK_HOLE); - if (hole_start == -1 && errno == ENXIO) - /* no more holes */ - break; - if (hole_start == -1) { - perror ("no more holes"); - break; - } - - hole_end = glfs_lseek (fd, hole_start, SEEK_DATA); - if (hole_end == -1 && errno == ENXIO) { - /* no more data */ - break; - } - - printf ("HOLE found: %ld - %ld%s\n", hole_start, hole_end, - (hole_end == st.st_size) ? " (EOF)" : ""); - } - - glfs_close (fd); - - if (fs) { - glfs_fini (fs); - } + if (fs) { + glfs_fini(fs); + } - return ret; + return ret; } diff --git a/tests/basic/gfapi/upcall-cache-invalidate.c b/tests/basic/gfapi/upcall-cache-invalidate.c index 9add3381278..078286a8956 100644 --- a/tests/basic/gfapi/upcall-cache-invalidate.c +++ b/tests/basic/gfapi/upcall-cache-invalidate.c @@ -9,204 +9,201 @@ #include <glusterfs/api/glfs.h> #include <glusterfs/api/glfs-handles.h> -#define LOG_ERR(func, ret) do { \ - if (ret != 0) { \ - fprintf (stderr, "%s : returned error %d (%s)\n", \ - func, ret, strerror (errno)); \ - goto out; \ - } else { \ - fprintf (stderr, "%s : returned %d\n", func, ret); \ - } \ - } while (0) +#define LOG_ERR(func, ret) \ + do { \ + if (ret != 0) { \ + fprintf(stderr, "%s : returned error %d (%s)\n", func, ret, \ + strerror(errno)); \ + goto out; \ + } else { \ + fprintf(stderr, "%s : returned %d\n", func, ret); \ + } \ + } while (0) int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { - glfs_t *fs = NULL; - glfs_t *fs2 = NULL; - glfs_t *fs_tmp = NULL; - glfs_t *fs_tmp2 = NULL; - int ret = 0, i; - glfs_fd_t *fd = NULL; - glfs_fd_t *fd2 = NULL; - glfs_fd_t *fd_tmp = NULL; - glfs_fd_t *fd_tmp2 = NULL; - char readbuf[32]; - char *filename = "file_tmp"; - char *writebuf = NULL; - char *vol_id = NULL; - unsigned int cnt = 1; - struct glfs_upcall *cbk = NULL; - char *logfile = NULL; - char *volname = NULL; - char *hostname = NULL; - - if (argc != 4) { - fprintf (stderr, "Invalid argument\n"); - exit(1); + glfs_t *fs = NULL; + glfs_t *fs2 = NULL; + glfs_t *fs_tmp = NULL; + glfs_t *fs_tmp2 = NULL; + int ret = 0, i; + glfs_fd_t *fd = NULL; + glfs_fd_t *fd2 = NULL; + glfs_fd_t *fd_tmp = NULL; + glfs_fd_t *fd_tmp2 = NULL; + char readbuf[32]; + char *filename = "file_tmp"; + char *writebuf = NULL; + char *vol_id = NULL; + unsigned int cnt = 1; + struct glfs_upcall *cbk = NULL; + char *logfile = NULL; + char *volname = NULL; + char *hostname = NULL; + + if (argc != 4) { + fprintf(stderr, "Invalid argument\n"); + exit(1); + } + + hostname = argv[1]; + volname = argv[2]; + logfile = argv[3]; + + fs = glfs_new(volname); + if (!fs) { + fprintf(stderr, "glfs_new: returned NULL\n"); + return -1; + } + + ret = glfs_set_volfile_server(fs, "tcp", hostname, 24007); + LOG_ERR("glfs_set_volfile_server", ret); + + ret = glfs_set_logging(fs, logfile, 7); + LOG_ERR("glfs_set_logging", ret); + + ret = glfs_init(fs); + LOG_ERR("glfs_init", ret); + + /* This does not block, but enables caching of events. Real + * applications like NFS-Ganesha run this in a thread before activity + * on the fs (through this instance) happens. */ + ret = glfs_h_poll_upcall(fs_tmp, &cbk); + LOG_ERR("glfs_h_poll_upcall", ret); + + fs2 = glfs_new(volname); + if (!fs2) { + fprintf(stderr, "glfs_new fs2: returned NULL\n"); + return 1; + } + + ret = glfs_set_volfile_server(fs2, "tcp", hostname, 24007); + LOG_ERR("glfs_set_volfile_server-fs2", ret); + + ret = glfs_set_logging(fs2, logfile, 7); + LOG_ERR("glfs_set_logging-fs2", ret); + + ret = glfs_init(fs2); + LOG_ERR("glfs_init-fs2", ret); + + fd = glfs_creat(fs, filename, O_RDWR | O_SYNC, 0644); + if (fd <= 0) { + ret = -1; + LOG_ERR("glfs_creat", ret); + } + fprintf(stderr, "glfs-create fd - %d\n", fd); + + fd2 = glfs_open(fs2, filename, O_SYNC | O_RDWR | O_CREAT); + if (fd2 <= 0) { + ret = -1; + LOG_ERR("glfs_open-fs2", ret); + } + fprintf(stderr, "glfs-open fd2 - %d\n", fd2); + + do { + if (cnt % 2) { + fd_tmp = fd; + fs_tmp = fs; + fd_tmp2 = fd2; + fs_tmp2 = fs2; + } else { + fd_tmp = fd2; + fs_tmp = fs2; + fd_tmp2 = fd; + fs_tmp2 = fs; } - hostname = argv[1]; - volname = argv[2]; - logfile = argv[3]; - - fs = glfs_new (volname); - if (!fs) { - fprintf (stderr, "glfs_new: returned NULL\n"); - return -1; + /* WRITE on fd_tmp */ + writebuf = malloc(10); + if (writebuf) { + memcpy(writebuf, "abcd", 4); + ret = glfs_write(fd_tmp, writebuf, 4, 0); + if (ret <= 0) { + ret = -1; + LOG_ERR("glfs_write", ret); + } else { + fprintf(stderr, "glfs_write succeeded\n"); + } + free(writebuf); + } else { + fprintf(stderr, "Could not allocate writebuf\n"); + return -1; } - ret = glfs_set_volfile_server (fs, "tcp", hostname, 24007); - LOG_ERR("glfs_set_volfile_server", ret); - - ret = glfs_set_logging (fs, logfile, 7); - LOG_ERR("glfs_set_logging", ret); - - ret = glfs_init (fs); - LOG_ERR("glfs_init", ret); + /* READ on fd_tmp2 */ + ret = glfs_lseek(fd_tmp2, 0, SEEK_SET); + LOG_ERR("glfs_lseek", ret); - /* This does not block, but enables caching of events. Real - * applications like NFS-Ganesha run this in a thread before activity - * on the fs (through this instance) happens. */ - ret = glfs_h_poll_upcall(fs_tmp, &cbk); - LOG_ERR ("glfs_h_poll_upcall", ret); + memset(readbuf, 0, sizeof(readbuf)); + ret = glfs_pread(fd_tmp2, readbuf, 4, 0, 0, NULL); - fs2 = glfs_new (volname); - if (!fs2) { - fprintf (stderr, "glfs_new fs2: returned NULL\n"); - return 1; + if (ret <= 0) { + ret = -1; + LOG_ERR("glfs_pread", ret); + } else { + fprintf(stderr, "glfs_read: %s\n", readbuf); } - ret = glfs_set_volfile_server (fs2, "tcp", hostname, 24007); - LOG_ERR("glfs_set_volfile_server-fs2", ret); - - ret = glfs_set_logging (fs2, logfile, 7); - LOG_ERR("glfs_set_logging-fs2", ret); - - ret = glfs_init (fs2); - LOG_ERR("glfs_init-fs2", ret); - - fd = glfs_creat(fs, filename, O_RDWR|O_SYNC, 0644); - if (fd <= 0) { + /* Open() fops seem to be not performed on server side until + * there are I/Os on that fd + */ + if (cnt > 2) { + struct glfs_upcall_inode *in_arg = NULL; + enum glfs_upcall_reason reason = 0; + struct glfs_object *object = NULL; + uint64_t flags = 0; + uint64_t expire = 0; + + ret = glfs_h_poll_upcall(fs_tmp, &cbk); + LOG_ERR("glfs_h_poll_upcall", ret); + + reason = glfs_upcall_get_reason(cbk); + + /* Expect 'GLFS_INODE_INVALIDATE' upcall event. */ + if (reason == GLFS_UPCALL_INODE_INVALIDATE) { + in_arg = glfs_upcall_get_event(cbk); + + object = glfs_upcall_inode_get_object(in_arg); + flags = glfs_upcall_inode_get_flags(in_arg); + expire = glfs_upcall_inode_get_expire(in_arg); + + fprintf(stderr, + " upcall event type - %d," + " object(%p), flags(%d), " + " expire_time_attr(%d)\n", + reason, object, flags, expire); + } else { + fprintf(stderr, "Didn't receive upcall notify event"); ret = -1; - LOG_ERR ("glfs_creat", ret); - } - fprintf (stderr, "glfs-create fd - %d\n", fd); + goto err; + } - fd2 = glfs_open(fs2, filename, O_SYNC|O_RDWR|O_CREAT); - if (fd2 <= 0) { - ret = -1; - LOG_ERR ("glfs_open-fs2", ret); + glfs_free(cbk); } - fprintf (stderr, "glfs-open fd2 - %d\n", fd2); - - do { - if (cnt%2) { - fd_tmp = fd; - fs_tmp = fs; - fd_tmp2 = fd2; - fs_tmp2 = fs2; - } else { - fd_tmp = fd2; - fs_tmp = fs2; - fd_tmp2 = fd; - fs_tmp2 = fs; - } - - /* WRITE on fd_tmp */ - writebuf = malloc(10); - if (writebuf) { - memcpy (writebuf, "abcd", 4); - ret = glfs_write (fd_tmp, writebuf, 4, 0); - if (ret <= 0) { - ret = -1; - LOG_ERR ("glfs_write", ret); - } else { - fprintf (stderr, - "glfs_write suceeded\n"); - } - free(writebuf); - } else { - fprintf (stderr, - "Could not allocate writebuf\n"); - return -1; - } - - /* READ on fd_tmp2 */ - ret = glfs_lseek (fd_tmp2, 0, SEEK_SET); - LOG_ERR ("glfs_lseek", ret); - - memset (readbuf, 0, sizeof(readbuf)); - ret = glfs_pread (fd_tmp2, readbuf, 4, 0, 0); - - if (ret <= 0) { - ret = -1; - LOG_ERR ("glfs_pread", ret); - } else { - fprintf (stderr, "glfs_read: %s\n", readbuf); - } - - /* Open() fops seem to be not performed on server side until - * there are I/Os on that fd - */ - if (cnt > 2) { - struct glfs_upcall_inode *in_arg = NULL; - enum glfs_upcall_reason reason = 0; - struct glfs_object *object = NULL; - uint64_t flags = 0; - uint64_t expire = 0; - - ret = glfs_h_poll_upcall(fs_tmp, &cbk); - LOG_ERR ("glfs_h_poll_upcall", ret); - - reason = glfs_upcall_get_reason (cbk); - - /* Expect 'GLFS_INODE_INVALIDATE' upcall event. */ - if (reason == GLFS_UPCALL_INODE_INVALIDATE) { - in_arg = glfs_upcall_get_event (cbk); - - object = glfs_upcall_inode_get_object (in_arg); - flags = glfs_upcall_inode_get_flags (in_arg); - expire = glfs_upcall_inode_get_expire (in_arg); - - fprintf (stderr, " upcall event type - %d," - " object(%p), flags(%d), " - " expire_time_attr(%d)\n" , - reason, object, flags, expire); - } else { - fprintf (stderr, - "Didnt receive upcall notify event"); - ret = -1; - goto err; - } - - glfs_free (cbk); - } - - sleep(5); - } while (++cnt < 5); + + sleep(5); + } while (++cnt < 5); err: - glfs_close(fd); - LOG_ERR ("glfs_close", ret); + glfs_close(fd); + LOG_ERR("glfs_close", ret); - glfs_close(fd2); - LOG_ERR ("glfs_close-fd2", ret); + glfs_close(fd2); + LOG_ERR("glfs_close-fd2", ret); out: - if (fs) { - ret = glfs_fini(fs); - fprintf (stderr, "glfs_fini(fs) returned %d \n", ret); - } - - if (fs2) { - ret = glfs_fini(fs2); - fprintf (stderr, "glfs_fini(fs2) returned %d \n", ret); - } - - if (ret) - exit(1); - exit(0); + if (fs) { + ret = glfs_fini(fs); + fprintf(stderr, "glfs_fini(fs) returned %d \n", ret); + } + + if (fs2) { + ret = glfs_fini(fs2); + fprintf(stderr, "glfs_fini(fs2) returned %d \n", ret); + } + + if (ret) + exit(1); + exit(0); } - - diff --git a/tests/basic/gfapi/upcall-register-api.c b/tests/basic/gfapi/upcall-register-api.c new file mode 100644 index 00000000000..53ce0ecdb68 --- /dev/null +++ b/tests/basic/gfapi/upcall-register-api.c @@ -0,0 +1,286 @@ +#include <fcntl.h> +#include <unistd.h> +#include <time.h> +#include <limits.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <glusterfs/api/glfs.h> +#include <glusterfs/api/glfs-handles.h> + +#define LOG_ERR(func, ret) \ + do { \ + if (ret != 0) { \ + fprintf(stderr, "%s : returned error %d (%s)\n", func, ret, \ + strerror(errno)); \ + goto out; \ + } else { \ + fprintf(stderr, "%s : returned %d\n", func, ret); \ + } \ + } while (0) + +int upcall_recv = 0; + +void +up_async_invalidate(struct glfs_upcall *up_arg, void *data) +{ + struct glfs_upcall_inode *in_arg = NULL; + enum glfs_upcall_reason reason = 0; + struct glfs_object *object = NULL; + uint64_t flags = 0; + uint64_t expire = 0; + + if (!up_arg) + return; + + reason = glfs_upcall_get_reason(up_arg); + + /* Expect 'GLFS_INODE_INVALIDATE' upcall event. */ + + if (reason == GLFS_UPCALL_INODE_INVALIDATE) { + in_arg = glfs_upcall_get_event(up_arg); + + object = glfs_upcall_inode_get_object(in_arg); + flags = glfs_upcall_inode_get_flags(in_arg); + expire = glfs_upcall_inode_get_expire(in_arg); + + fprintf(stderr, + " upcall event type - %d," + " object(%p), flags(%d), " + " expire_time_attr(%d)\n", + reason, object, flags, expire); + upcall_recv++; + } + + glfs_free(up_arg); + return; +} + +int +perform_io(glfs_t *fs, glfs_t *fs2, int cnt) +{ + glfs_t *fs_tmp = NULL; + glfs_t *fs_tmp2 = NULL; + glfs_fd_t *fd_tmp = NULL; + glfs_fd_t *fd_tmp2 = NULL; + char readbuf[32]; + char *writebuf = NULL; + glfs_fd_t *fd = NULL; + glfs_fd_t *fd2 = NULL; + char *filename = "file_tmp"; + int ret = -1; + + if (!fs || !fs2) + return -1; + + /* Create file from fs and open it from fs2 */ + fd = glfs_creat(fs, filename, O_RDWR | O_SYNC, 0644); + if (fd <= 0) { + ret = -1; + LOG_ERR("glfs_creat", ret); + } + + fd2 = glfs_open(fs2, filename, O_SYNC | O_RDWR | O_CREAT); + if (fd2 <= 0) { + ret = -1; + LOG_ERR("glfs_open-fs2", ret); + } + + do { + if (cnt % 2) { + fd_tmp = fd; + fs_tmp = fs; + fd_tmp2 = fd2; + fs_tmp2 = fs2; + } else { + fd_tmp = fd2; + fs_tmp = fs2; + fd_tmp2 = fd; + fs_tmp2 = fs; + } + + /* WRITE on fd_tmp */ + writebuf = malloc(10); + if (writebuf) { + memcpy(writebuf, "abcd", 4); + ret = glfs_write(fd_tmp, writebuf, 4, 0); + if (ret <= 0) { + ret = -1; + LOG_ERR("glfs_write", ret); + } + free(writebuf); + } else { + fprintf(stderr, "Could not allocate writebuf\n"); + return -1; + } + + /* READ on fd_tmp2 */ + ret = glfs_lseek(fd_tmp2, 0, SEEK_SET); + LOG_ERR("glfs_lseek", ret); + + memset(readbuf, 0, sizeof(readbuf)); + ret = glfs_pread(fd_tmp2, readbuf, 4, 0, 0, NULL); + + if (ret <= 0) { + ret = -1; + LOG_ERR("glfs_pread", ret); + } + + sleep(2); + } while (--cnt > 0); + + sleep(2); + + ret = 0; +err: + glfs_close(fd); + + glfs_close(fd2); + +out: + return ret; +} + +int +main(int argc, char *argv[]) +{ + glfs_t *fs = NULL; + glfs_t *fs2 = NULL; + int ret = 0, i; + char *vol_id = NULL; + unsigned int cnt = 5; + struct glfs_upcall *cbk = NULL; + char *logfile = NULL; + char *volname = NULL; + char *hostname = NULL; + int up_events = GLFS_EVENT_ANY; + + if (argc != 4) { + fprintf(stderr, "Invalid argument\n"); + exit(1); + } + + hostname = argv[1]; + volname = argv[2]; + logfile = argv[3]; + + /* Initialize fs */ + fs = glfs_new(volname); + if (!fs) { + fprintf(stderr, "glfs_new: returned NULL\n"); + return -1; + } + + ret = glfs_set_volfile_server(fs, "tcp", hostname, 24007); + LOG_ERR("glfs_set_volfile_server", ret); + + ret = glfs_set_logging(fs, logfile, 7); + LOG_ERR("glfs_set_logging", ret); + + ret = glfs_init(fs); + LOG_ERR("glfs_init", ret); + + /* Initialize fs2 */ + fs2 = glfs_new(volname); + if (!fs2) { + fprintf(stderr, "glfs_new fs2: returned NULL\n"); + return 1; + } + + ret = glfs_set_volfile_server(fs2, "tcp", hostname, 24007); + LOG_ERR("glfs_set_volfile_server-fs2", ret); + + ret = glfs_set_logging(fs2, logfile, 7); + LOG_ERR("glfs_set_logging-fs2", ret); + + ret = glfs_init(fs2); + LOG_ERR("glfs_init-fs2", ret); + + /* Register Upcalls */ + ret = glfs_upcall_register(fs, up_events, up_async_invalidate, NULL); + + /* Check if the return mask contains the event */ + if (!(ret & GLFS_EVENT_INODE_INVALIDATE)) { + fprintf(stderr, + "glfs_upcall_register return doesn't contain" + " upcall event\n"); + return -1; + } + + ret = glfs_upcall_register(fs2, up_events, up_async_invalidate, NULL); + + /* Check if the return mask contains the event */ + if ((ret < 0) || !(ret & GLFS_EVENT_INODE_INVALIDATE)) { + fprintf(stderr, + "glfs_upcall_register return doesn't contain" + " upcall event\n"); + return -1; + } + + /* Perform I/O */ + ret = perform_io(fs, fs2, cnt); + LOG_ERR("perform_io", ret); + + if (upcall_recv == 0) { + fprintf(stderr, "Upcalls are not received.\n"); + ret = -1; + } else { + fprintf(stderr, "Received %d upcalls as expected\n", upcall_recv); + ret = 0; + } + + sleep(5); /* to flush out previous upcalls if any */ + + /* Now unregister and check there are no upcall events received */ + ret = glfs_upcall_unregister(fs, up_events); + + /* Check if the return mask contains the event */ + if ((ret < 0) || !(ret & GLFS_EVENT_INODE_INVALIDATE)) { + fprintf(stderr, + "glfs_upcall_unregister return doesn't contain" + " upcall event\n"); + return -1; + } + + ret = glfs_upcall_unregister(fs2, up_events); + + /* Check if the return mask contains the event */ + if ((ret < 0) || !(ret & GLFS_EVENT_INODE_INVALIDATE)) { + fprintf(stderr, + "glfs_upcall_unregister return doesn't contain" + " upcall event\n"); + return -1; + } + + upcall_recv = 0; + + ret = perform_io(fs, fs2, cnt); + LOG_ERR("perform_io", ret); + + if (upcall_recv != 0) { + fprintf(stderr, "%d upcalls received even after unregister.\n", + upcall_recv); + ret = -1; + } else { + fprintf(stderr, + "Post unregister, no upcalls received as" + " expected\n"); + ret = 0; + } + +out: + if (fs) { + ret = glfs_fini(fs); + fprintf(stderr, "glfs_fini(fs) returned %d\n", ret); + } + + if (fs2) { + ret = glfs_fini(fs2); + fprintf(stderr, "glfs_fini(fs2) returned %d\n", ret); + } + + if (ret) + exit(1); + exit(0); +} diff --git a/tests/basic/gfapi/upcall-register-api.t b/tests/basic/gfapi/upcall-register-api.t new file mode 100755 index 00000000000..a46234ed7af --- /dev/null +++ b/tests/basic/gfapi/upcall-register-api.t @@ -0,0 +1,30 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup; + +TEST glusterd + +TEST $CLI volume create $V0 $H0:$B0/brick1; +EXPECT 'Created' volinfo_field $V0 'Status'; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +logdir=`gluster --print-logdir` + +## Enable Upcall cache-invalidation feature +TEST $CLI volume set $V0 features.cache-invalidation on; + +TEST build_tester $(dirname $0)/upcall-register-api.c -lgfapi + +TEST ./$(dirname $0)/upcall-register-api $H0 $V0 $logdir/upcall-register-api.log + +cleanup_tester $(dirname $0)/upcall-register-api + +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 + +cleanup; |
