diff options
author | ShyamsundarR <srangana@redhat.com> | 2018-11-21 09:43:23 -0500 |
---|---|---|
committer | Amar Tumballi <amarts@redhat.com> | 2019-01-07 14:43:27 +0000 |
commit | c31f1c232a6673c4e3fc3188e15ae0e708a54613 (patch) | |
tree | 195a5c281b7d88991fb9bdc3c4570fec6ca95366 /tests/basic | |
parent | f99f51ca87fd8703947df985901cbce37bc6c818 (diff) |
gfapi: new api glfs_statx as linux's statx
Change-Id: I44dd6ceef0954ae7fc13f920e84d81bbd3f6a774
Updates: #389
Signed-off-by: Kinglong Mee <mijinlong@open-fs.com>
Signed-off-by: ShyamsundarR <srangana@redhat.com>
Diffstat (limited to 'tests/basic')
-rw-r--r-- | tests/basic/gfapi/gfapi-statx-basic.c | 184 | ||||
-rwxr-xr-x | tests/basic/gfapi/gfapi-statx-basic.t | 30 |
2 files changed, 214 insertions, 0 deletions
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; |