diff options
Diffstat (limited to 'extras/test')
| -rwxr-xr-x | extras/test/bug-920583.t | 50 | ||||
| -rwxr-xr-x | extras/test/gluster_commands.sh | 265 | ||||
| -rw-r--r-- | extras/test/ld-preload-test/Makefile | 28 | ||||
| -rw-r--r-- | extras/test/ld-preload-test/README | 40 | ||||
| -rw-r--r-- | extras/test/ld-preload-test/ld-preload-lib.c | 615 | ||||
| -rw-r--r-- | extras/test/ld-preload-test/ld-preload-test.c | 358 | ||||
| -rwxr-xr-x | extras/test/ld-preload-test/test-preload.sh | 7 | ||||
| -rw-r--r-- | extras/test/open-fd-tests.c | 67 | ||||
| -rwxr-xr-x | extras/test/run.sh | 22 | ||||
| -rwxr-xr-x | extras/test/stop_glusterd.sh | 19 | ||||
| -rw-r--r-- | extras/test/test-ffop.c | 920 |
11 files changed, 2391 insertions, 0 deletions
diff --git a/extras/test/bug-920583.t b/extras/test/bug-920583.t new file mode 100755 index 00000000000..eedbb800ac0 --- /dev/null +++ b/extras/test/bug-920583.t @@ -0,0 +1,50 @@ +#!/bin/bash + +##Copy this file to tests/bugs before running run.sh (cp extras/test/bug-920583.t tests/bugs/) + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; +logdir=`gluster --print-logdir` + +## Start and create a volume +TEST glusterd; +TEST pidof glusterd; + +TEST $CLI volume create $V0 replica 2 stripe 2 $H0:$B0/${V0}{1,2,3,4,5,6,7,8}; + +## Verify volume is is created +EXPECT "$V0" volinfo_field $V0 'Volume Name'; +EXPECT 'Created' volinfo_field $V0 'Status'; + +## Start volume and verify +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +function log-file-name() +{ + logfilename=$M0".log" + echo ${logfilename:1} | tr / - +} + +log_file=$logdir"/"`log-file-name` + +lookup_unhashed_count=`grep "adding option 'lookup-unhashed'" $log_file | wc -l` +no_child_down_count=`grep "adding option 'assert-no-child-down'" $log_file | wc -l` +mount -t glusterfs $H0:/$V0 $M0 -o "xlator-option=*dht.assert-no-child-down=yes,xlator-option=*dht.lookup-unhashed=yes" +touch $M0/file1; + +new_lookup_unhashed_count=`grep "adding option 'lookup-unhashed'" $log_file | wc -l` +new_no_child_down_count=`grep "adding option 'assert-no-child-down'" $log_file | wc -l` +EXPECT "1" expr $new_lookup_unhashed_count - $lookup_unhashed_count +EXPECT "1" expr $new_no_child_down_count - $no_child_down_count + +## Finish up +TEST $CLI volume stop $V0; +EXPECT 'Stopped' volinfo_field $V0 'Status'; + +TEST $CLI volume delete $V0; +TEST ! $CLI volume info $V0; + +cleanup; diff --git a/extras/test/gluster_commands.sh b/extras/test/gluster_commands.sh new file mode 100755 index 00000000000..cb2a55fd5b5 --- /dev/null +++ b/extras/test/gluster_commands.sh @@ -0,0 +1,265 @@ +#!/bin/bash + + +# Copyright (c) 2006-2012 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. + + +# This script tests the basics gluster cli commands. + +echo "Starting glusterd" +glusterd +if [ $? -ne 0 ]; then + echo "Could not start glusterd.Exiting" + exit; +else + echo "glusterd started" +fi + +if [ ! -d "/exports" ]; then + mkdir /exports; + mkdir /exports/exp{1..10}; +else + mkdir /exports/exp{1..10}; +fi + +if [ ! -d "/mnt/client" ]; then + mkdir /mnt/client -p; +fi + + +set -e #exit at the first error that happens + +# create distribute volume and try start, mount, add-brick, replace-brick, remove-brick, stop, unmount, delete + +echo "Creating distribute volume........" +gluster volume create vol `hostname`:/exports/exp1 +gluster volume info + +echo "Starting distribute volume........" +gluster volume start vol +gluster volume info +sleep 1 +mount -t glusterfs `hostname`:vol /mnt/client +sleep 1 +df -h + +echo "adding-brick......." +gluster volume add-brick vol `hostname`:/exports/exp2 +gluster volume info +sleep 1 +umount /mnt/client +mount -t glusterfs `hostname`:vol /mnt/client +df -h +sleep 1 + +echo "replacing brick......" +gluster volume replace-brick vol `hostname`:/exports/exp1 `hostname`:/exports/exp3 start +#sleep for 5 seconds +sleep 5 +gluster volume replace-brick vol `hostname`:/exports/exp1 `hostname`:/exports/exp3 status +gluster volume replace-brick vol `hostname`:/exports/exp1 `hostname`:/exports/exp3 pause +gluster volume replace-brick vol `hostname`:/exports/exp1 `hostname`:/exports/exp3 status +gluster volume replace-brick vol `hostname`:/exports/exp1 `hostname`:/exports/exp3 start +#sleep for 5 seconds +sleep 5 +gluster volume replace-brick vol `hostname`:/exports/exp1 `hostname`:/exports/exp3 status +gluster volume replace-brick vol `hostname`:/exports/exp1 `hostname`:/exports/exp3 commit + + +echo "replcing brick for abort operation" +gluster volume replace-brick vol `hostname`:/exports/exp3 `hostname`:/exports/exp1 start +#sleep for 5 seconds +sleep 5 +gluster volume replace-brick vol `hostname`:/exports/exp3 `hostname`:/exports/exp1 status +gluster volume replace-brick vol `hostname`:/exports/exp3 `hostname`:/exports/exp1 pause +gluster volume replace-brick vol `hostname`:/exports/exp3 `hostname`:/exports/exp1 status +gluster volume replace-brick vol `hostname`:/exports/exp3 `hostname`:/exports/exp1 start +#sleep for 5 seconds +sleep 5 +gluster volume replace-brick vol `hostname`:/exports/exp3 `hostname`:/exports/exp1 status +gluster volume replace-brick vol `hostname`:/exports/exp3 `hostname`:/exports/exp1 abort + + +gluster volume info +sleep 1 +df -h +sleep 1 + +echo "removing brick......." +gluster --mode=script volume remove-brick vol `hostname`:/exports/exp2 +gluster volume info +sleep 1 +df -h +sleep 1 + +echo "stopping distribute volume......" +gluster --mode=script volume stop vol +gluster volume info +sleep 1 +umount /mnt/client +df -h + +echo "deleting distribute volume......" +gluster --mode=script volume delete vol +gluster volume info +sleep 1 + +# create replicate volume and try start, mount, add-brick, replace-brick, remove-brick, stop, unmount, delete +echo "creating replicate volume......" +gluster volume create mirror replica 2 `hostname`:/exports/exp1 `hostname`:/exports/exp2 +gluster volume info +sleep 1 + +echo "starting replicate volume......" +gluster volume start mirror +gluster volume info +sleep 1 +mount -t glusterfs `hostname`:mirror /mnt/client +sleep 1 +df -h +sleep 1 + +echo "adding-brick......." +gluster volume add-brick mirror `hostname`:/exports/exp3 `hostname`:/exports/exp4 +gluster volume info +sleep 1 +df -h +sleep 1 + +echo "replacing-brick....." +gluster volume replace-brick mirror `hostname`:/exports/exp1 `hostname`:/exports/exp5 start +#sleep for 5 seconds +sleep 5 +gluster volume replace-brick mirror `hostname`:/exports/exp1 `hostname`:/exports/exp5 status +gluster volume replace-brick mirror `hostname`:/exports/exp1 `hostname`:/exports/exp5 pause +gluster volume replace-brick mirror `hostname`:/exports/exp1 `hostname`:/exports/exp5 status +gluster volume replace-brick mirror `hostname`:/exports/exp1 `hostname`:/exports/exp5 start +#sleep for 5 seconds +sleep 5 +gluster volume replace-brick mirror `hostname`:/exports/exp1 `hostname`:/exports/exp5 status +gluster volume replace-brick mirror `hostname`:/exports/exp1 `hostname`:/exports/exp5 commit +gluster volume info +sleep 1 +df -h +sleep 1 + +echo "replacing brick for abort operation" +gluster volume replace-brick mirror `hostname`:/exports/exp5 `hostname`:/exports/exp1 start +#sleep for 5 seconds +sleep 5 +gluster volume replace-brick mirror `hostname`:/exports/exp5 `hostname`:/exports/exp1 status +gluster volume replace-brick mirror `hostname`:/exports/exp5 `hostname`:/exports/exp1 pause +gluster volume replace-brick mirror `hostname`:/exports/exp5 `hostname`:/exports/exp1 status +gluster volume replace-brick mirror `hostname`:/exports/exp5 `hostname`:/exports/exp1 start +#sleep for 5 seconds +sleep 5 +gluster volume replace-brick mirror `hostname`:/exports/exp5 `hostname`:/exports/exp1 status +gluster volume replace-brick mirror `hostname`:/exports/exp5 `hostname`:/exports/exp1 abort + +gluster volume info +sleep 1 +df -h +sleep 1 + +echo "removeing-brick....." +gluster --mode=script volume remove-brick mirror `hostname`:/exports/exp3 `hostname`:/exports/exp4 +gluster volume info +sleep 1 +df -h +sleep 1 + +echo "stopping replicate volume....." +gluster --mode=script volume stop mirror +gluster volume info +sleep 1 +umount /mnt/client +df -h + +echo "deleting replicate volume....." +gluster --mode=script volume delete mirror +gluster volume info +sleep 1 + +# create stripe volume and try start, mount, add-brick, replace-brick, remove-brick, stop, unmount, delete + +echo "creating stripe volume....." +gluster volume create str stripe 2 `hostname`:/exports/exp1 `hostname`:/exports/exp2 +gluster volume info +sleep 1 + +echo "starting stripe volume....." +gluster volume start str +gluster volume info +sleep 1 +mount -t glusterfs `hostname`:str /mnt/client +sleep 1 +df -h +sleep 1 + +echo "adding brick...." +gluster volume add-brick str `hostname`:/exports/exp3 `hostname`:/exports/exp4 +gluster volume info +sleep 1 +df -h +sleep 1 + +echo "replacing brick....." +gluster volume replace-brick str `hostname`:/exports/exp1 `hostname`:/exports/exp5 start +#sleep for 5 seconds +sleep 5 +gluster volume replace-brick str `hostname`:/exports/exp1 `hostname`:/exports/exp5 status +gluster volume replace-brick str `hostname`:/exports/exp1 `hostname`:/exports/exp5 pause +gluster volume replace-brick str `hostname`:/exports/exp1 `hostname`:/exports/exp5 status +gluster volume replace-brick str `hostname`:/exports/exp1 `hostname`:/exports/exp5 start +#sleep for 5 seconds +sleep 5 +gluster volume replace-brick str `hostname`:/exports/exp1 `hostname`:/exports/exp5 status +gluster volume replace-brick str `hostname`:/exports/exp1 `hostname`:/exports/exp5 commit + +gluster volume info +sleep 1 +df -h +sleep 1 + +echo "replacing brick for abort operation" +gluster volume replace-brick str `hostname`:/exports/exp5 `hostname`:/exports/exp1 start +#sleep for 5 seconds +sleep 5 +gluster volume replace-brick str `hostname`:/exports/exp5 `hostname`:/exports/exp1 status +gluster volume replace-brick str `hostname`:/exports/exp5 `hostname`:/exports/exp1 pause +gluster volume replace-brick str `hostname`:/exports/exp5 `hostname`:/exports/exp1 status +gluster volume replace-brick str `hostname`:/exports/exp5 `hostname`:/exports/exp1 start +#sleep for 5 seconds +sleep 5 +gluster volume replace-brick str `hostname`:/exports/exp5 `hostname`:/exports/exp1 status +gluster volume replace-brick str `hostname`:/exports/exp5 `hostname`:/exports/exp1 abort + +gluster volume info +sleep 1 +df -h +sleep 1 + +echo "removing-brick....." +gluster --mode=script volume remove-brick str `hostname`:/exports/exp3 `hostname`:/exports/exp4 +gluster volume info +sleep 1 +df -h +sleep 1 + +echo "stopping stripe volume....." +gluster --mode=script volume stop str +gluster volume info +sleep 1 +umount /mnt/client +df -h + +echo "deleting stripe volume....." +gluster --mode=script volume delete str +gluster volume info + diff --git a/extras/test/ld-preload-test/Makefile b/extras/test/ld-preload-test/Makefile new file mode 100644 index 00000000000..97aa016518d --- /dev/null +++ b/extras/test/ld-preload-test/Makefile @@ -0,0 +1,28 @@ +TOOL_CFLAGS32=-g -O0 -Wall +TOOL_CFLAGS64=-g -O0 -D_GNU_SOURCE -Wall -D_FILE_OFFSET_BITS=64 +LIB_CFLAGS=-g -O0 -fPIC -Wall -shared -ldl +%LIB_CFLAGS=-g -O0 -D_GNU_SOURCE -fPIC -Wall -shared -D_FILE_OFFSET_BITS=64 -ldl + +all: ld-preload-test32 ld-preload-test64 ld-preload-lib + + +copy32: + cp ld-preload-test.c test32.c + +ld-preload-test32: copy32 + gcc ${TOOL_CFLAGS32} test32.c -o ld-preload-test32 + rm -f test32.c + +copy64: + cp ld-preload-test.c test64.c + +ld-preload-test64: copy64 + gcc ${TOOL_CFLAGS64} test64.c -o ld-preload-test64 + rm -f test64.c + +ld-preload-lib: ld-preload-lib.c + gcc ${LIB_CFLAGS} ld-preload-lib.c -o ld-preload-lib.so + +clean: + rm -f ld-preload-test32 ld-preload-test64 ld-preload-lib.so + diff --git a/extras/test/ld-preload-test/README b/extras/test/ld-preload-test/README new file mode 100644 index 00000000000..df80003844b --- /dev/null +++ b/extras/test/ld-preload-test/README @@ -0,0 +1,40 @@ +ld-preload-test +=============== +1. The idea of this test tool is to check the sanity of the LD_PRELOAD +mechanism in libc for the system on which booster needs to run. + +2. Basically, this test tool calls various system calls for which there is +support in the booster library. Combined with the logging output from this +tool and the preload-test-lib, one can determine whether the +pre-loading mechanism is working working in order for booster to initialize. + +3. This tool does not test GlusterFS functionality running under booster +although the path specified to the tool can be a GlusterFS mountpoint but +that is not very useful. + +4. This tool is incomplete without the preload-test-lib and the +accompanyung shell script that needs to be run for running the test. + +ld-preload-lib.so +================= +A very simple library that intercepts booster supported system calls +and prints a log message to stdout. +Combined with the ld-preload-test, we cam determine whether all system calls +are getting redirected into this library when LD_PRELOAD'ed. This helps us +conduct a basic test to ensure that the required syscalls actually will +be intercepted by the booster library. + + +Instructions +============ + +1. Build the binaries. + $ make + +(We've tested the tool on Debian and CentOS. If there are build errors or +warnings, please do report them to gluster-devel@gluster.org.) + +2. Run the test. + $ ./test-preload.sh > preload.log + +3. Mail the log to gluster-devel@gluster.org. diff --git a/extras/test/ld-preload-test/ld-preload-lib.c b/extras/test/ld-preload-test/ld-preload-lib.c new file mode 100644 index 00000000000..d120c053a69 --- /dev/null +++ b/extras/test/ld-preload-test/ld-preload-lib.c @@ -0,0 +1,615 @@ +/* + Copyright (c) 2007-2012 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. +*/ + +/* LD PRELOAD'able library + * A very simple library that intercepts booster supported system calls + * and prints a log message to stdout. + * + * Combined with the ld-preload-test, we cam determine whether all system calls + * are getting redirected into this library when LD_PRELOAD'ed. This helps us + * conduct a basic test to ensure that the required syscalls actually will + * be intercepted by the booster library. + */ + +#include <dlfcn.h> +#include <sys/types.h> +#include <sys/uio.h> +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <inttypes.h> +#include <string.h> +#include <assert.h> +#include <errno.h> +#include <utime.h> +#include <sys/statfs.h> +#include <sys/statvfs.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <dirent.h> +#include <sys/xattr.h> +#include <sys/sendfile.h> + +/* Err number that is assigned to errno so that test application can + * verify that the function was intercepted correctly. + */ +#define PRELOAD_ERRNO_VERF 6449 +#define set_errno() (errno = PRELOAD_ERRNO_VERF) + +void +intercept(char *call, int tabs) +{ + while (tabs > 0) { + fprintf(stdout, "\t"); + --tabs; + } + + fprintf(stdout, "Intercepted by %s", call); +} + +int +creat64(const char *pathname, mode_t mode) +{ + intercept("creat64", 2); + set_errno(); + return -1; +} + +int +creat(const char *pathname, mode_t mode) +{ + intercept("creat", 2); + set_errno(); + return -1; +} + +int +close(int fd) +{ + intercept("close", 2); + set_errno(); + return -1; +} + +int +open64(const char *pathname, int flags, ...) +{ + intercept("open64", 2); + set_errno(); + return -1; +} + +int +open(const char *pathname, int flags, ...) +{ + intercept("open", 2); + set_errno(); + return -1; +} + +ssize_t +read(int fd, void *buf, size_t count) +{ + intercept("read", 2); + set_errno(); + return -1; +} + +ssize_t +readv(int fd, const struct iovec *vector, int count) +{ + intercept("readv", 2); + set_errno(); + return -1; +} + +ssize_t +pread(int fd, void *buf, size_t count, unsigned long offset) +{ + intercept("pread", 2); + set_errno(); + return -1; +} + +ssize_t +pread64(int fd, void *buf, size_t count, uint64_t offset) +{ + intercept("pread64", 2); + set_errno(); + return -1; +} + +ssize_t +write(int fd, const void *buf, size_t count) +{ + intercept("write", 2); + set_errno(); + return -1; +} + +ssize_t +writev(int fd, const struct iovec *vector, int count) +{ + intercept("writev", 2); + set_errno(); + return -1; +} + +ssize_t +pwrite(int fd, const void *buf, size_t count, unsigned long offset) +{ + intercept("pwrite", 2); + set_errno(); + return -1; +} + +ssize_t +pwrite64(int fd, const void *buf, size_t count, uint64_t offset) +{ + intercept("pwrite64", 2); + set_errno(); + return -1; +} + +off_t +lseek(int fildes, unsigned long offset, int whence) +{ + intercept("lseek", 2); + set_errno(); + return -1; +} + +off_t +lseek64(int fildes, uint64_t offset, int whence) +{ + intercept("lseek64", 2); + set_errno(); + return -1; +} + +int +dup(int fd) +{ + intercept("dup", 2); + set_errno(); + return -1; +} + +int +dup2(int oldfd, int newfd) +{ + intercept("dup2", 2); + set_errno(); + return -1; +} + +int +mkdir(const char *pathname, mode_t mode) +{ + intercept("mkdir", 2); + set_errno(); + return -1; +} + +int +rmdir(const char *pathname) +{ + intercept("rmdir", 2); + set_errno(); + return -1; +} + +int +chmod(const char *pathname, mode_t mode) +{ + intercept("chmod", 2); + set_errno(); + return -1; +} + +int +chown(const char *pathname, uid_t owner, gid_t group) +{ + intercept("chown", 2); + set_errno(); + return -1; +} + +int +fchmod(int fd, mode_t mode) +{ + intercept("fchmod", 2); + set_errno(); + return -1; +} + +int +fchown(int fd, uid_t uid, gid_t gid) +{ + intercept("fchown", 2); + set_errno(); + return -1; +} + +int +fsync(int fd) +{ + intercept("fsync", 2); + set_errno(); + return -1; +} + +int +ftruncate(int fd, off_t length) +{ + intercept("ftruncate", 1); + set_errno(); + return -1; +} + +int +ftruncate64(int fd, off_t length) +{ + intercept("ftruncate64", 1); + set_errno(); + return -1; +} + +int +link(const char *oldpath, const char *newname) +{ + intercept("link", 2); + set_errno(); + return -1; +} + +int +rename(const char *oldpath, const char *newpath) +{ + intercept("rename", 2); + set_errno(); + return -1; +} + +int +utimes(const char *path, const struct timeval times[2]) +{ + intercept("utimes", 2); + set_errno(); + return -1; +} + +int +futimes(int fd, const struct timeval times[2]) +{ + intercept("futimes", 2); + set_errno(); + return -1; +} + +int +utime(const char *path, const struct utimbuf *buf) +{ + intercept("utime", 2); + set_errno(); + return -1; +} + +int +mknod(const char *path, mode_t mode, dev_t dev) +{ + intercept("mknod", 2); + set_errno(); + return -1; +} + +int +__xmknod(int ver, const char *path, mode_t mode, dev_t *dev) +{ + intercept("__xmknod", 2); + set_errno(); + return -1; +} + +int +mkfifo(const char *path, mode_t mode) +{ + intercept("mkfifo", 2); + set_errno(); + return -1; +} + +int +unlink(const char *path) +{ + intercept("unlink", 2); + set_errno(); + return -1; +} + +int +symlink(const char *oldpath, const char *newpath) +{ + intercept("symlink", 2); + set_errno(); + return -1; +} + +int +readlink(const char *path, char *buf, size_t bufsize) +{ + intercept("readlink", 1); + set_errno(); + return -1; +} + +char * +realpath(const char *path, char *resolved) +{ + intercept("realpath", 1); + set_errno(); + return NULL; +} + +DIR * +opendir(const char *path) +{ + intercept("opendir", 2); + set_errno(); + return NULL; +} + +struct dirent * +readdir(DIR *dir) +{ + intercept("readdir\t", 2); + set_errno(); + return NULL; +} + +struct dirent * +readdir64(DIR *dir) +{ + intercept("readdir64", 2); + set_errno(); + return NULL; +} + +int +readdir_r(DIR *dir, struct dirent *entry, struct dirent **result) +{ + intercept("readdir_r", 1); + set_errno(); + return -1; +} + +int +readdir64_r(DIR *dir, struct dirent *entry, struct dirent **result) +{ + intercept("readdir64_r", 1); + set_errno(); + return -1; +} + +int +closedir(DIR *dh) +{ + intercept("closedir", 1); + set_errno(); + return -1; +} + +int +__xstat(int ver, const char *path, struct stat *buf) +{ + intercept("__xstat\t", 2); + set_errno(); + return -1; +} + +int +__xstat64(int ver, const char *path, struct stat *buf) +{ + intercept("__xstat64", 2); + set_errno(); + return -1; +} + +int +stat(const char *path, struct stat *buf) +{ + intercept("stat", 2); + set_errno(); + return -1; +} + +int +stat64(const char *path, struct stat *buf) +{ + intercept("stat64", 2); + set_errno(); + return -1; +} + +int +__fxstat(int ver, int fd, struct stat *buf) +{ + intercept("__fxstat\t", 2); + set_errno(); + return -1; +} + +int +__fxstat64(int ver, int fd, struct stat *buf) +{ + intercept("__fxstat64", 2); + set_errno(); + return -1; +} + +int +fstat(int fd, struct stat *buf) +{ + intercept("fstat", 2); + set_errno(); + return -1; +} + +int +fstat64(int fd, struct stat *buf) +{ + intercept("fstat64", 2); + set_errno(); + return -1; +} + +int +__lxstat(int ver, const char *path, struct stat *buf) +{ + intercept("__lxstat\t", 2); + set_errno(); + return -1; +} + +int +__lxstat64(int ver, const char *path, struct stat *buf) +{ + intercept("__lxstat64", 2); + set_errno(); + return -1; +} + +int +lstat(const char *path, struct stat *buf) +{ + intercept("lstat", 2); + set_errno(); + return -1; +} + +int +lstat64(const char *path, struct stat *buf) +{ + intercept("lstat64", 2); + set_errno(); + return -1; +} + +int +statfs(const char *path, struct statfs *buf) +{ + intercept("statfs", 2); + set_errno(); + return -1; +} + +int +statfs64(const char *path, struct statfs *buf) +{ + intercept("statfs64", 2); + set_errno(); + return -1; +} + +int +statvfs(const char *path, struct statvfs *buf) +{ + intercept("statvfs\t", 2); + set_errno(); + return -1; +} + +int +statvfs64(const char *path, struct statvfs *buf) +{ + intercept("statvfs64", 2); + set_errno(); + return -1; +} + +ssize_t +getxattr(const char *path, const char *name, void *value, size_t size) +{ + intercept("getxattr", 1); + set_errno(); + return -1; +} + +ssize_t +lgetxattr(const char *path, const char *name, void *value, size_t size) +{ + intercept("lgetxattr", 1); + set_errno(); + return -1; +} + +int +remove(const char *path) +{ + intercept("remove", 2); + set_errno(); + return -1; +} + +int +lchown(const char *path, uid_t owner, gid_t group) +{ + intercept("lchown", 2); + set_errno(); + return -1; +} + +void +rewinddir(DIR *dirp) +{ + intercept("rewinddir", 1); + set_errno(); + return; +} + +void +seekdir(DIR *dirp, off_t offset) +{ + intercept("seekdir", 2); + set_errno(); + return; +} + +off_t +telldir(DIR *dirp) +{ + intercept("telldir", 2); + set_errno(); + return -1; +} + +ssize_t +sendfile(int out_fd, int in_fd, off_t *offset, size_t count) +{ + intercept("sendfile\t", 1); + set_errno(); + return -1; +} + +ssize_t +sendfile64(int out_fd, int in_fd, off_t *offset, size_t count) +{ + intercept("sendfile64", 1); + set_errno(); + return -1; +} + +int +fcntl(int fd, int cmd, ...) +{ + intercept("fcntl", 2); + set_errno(); + return -1; +} diff --git a/extras/test/ld-preload-test/ld-preload-test.c b/extras/test/ld-preload-test/ld-preload-test.c new file mode 100644 index 00000000000..54dde8c7d54 --- /dev/null +++ b/extras/test/ld-preload-test/ld-preload-test.c @@ -0,0 +1,358 @@ +/* + Copyright (c) 2007-2012 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. +*/ + +/* + * LD PRELOAD Test Tool + * + * 1. The idea of this test tool is to check the sanity of the LD_PRELOAD + * mechanism in libc for the system on which booster needs to run. + * + * 2. Basically, this test tool calls various system calls for which there is + * support in the booster library. Combined with the logging output from this + * tool and the preload-test-lib, one can determine whether the + * pre-loading mechanism is working working in order for booster to initialize. + * + * 3. This tool does not test GlusterFS functionality running under booster + * although the path specified to the tool can be a GlusterFS mountpoint but + * that is not very useful. + * + * 4. This tool is incomplete without the preload-test-lib and the + * accompanyung shell script that needs to be run for running the test. + */ +#define _XOPEN_SOURCE 500 + +#include <dlfcn.h> +#include <sys/types.h> +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <inttypes.h> +#include <string.h> +#include <assert.h> +#include <errno.h> +#include <dirent.h> +#include <sys/statfs.h> +#include <sys/statvfs.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/uio.h> +#include <utime.h> +#include <sys/time.h> +#include <sys/xattr.h> +#include <sys/sendfile.h> + +#define PRELOAD_ERRNO_VERF 6449 +void +check_err(int ret, char *call, int tabs) +{ + while (tabs > 0) { + fprintf(stdout, "\t"); + --tabs; + } + if (ret != -1) { + fprintf(stdout, "Not intercepted: %s\n", call); + return; + } + + if (errno != PRELOAD_ERRNO_VERF) { + fprintf(stdout, "Not intercepted: %s: err: %s\n", call, + strerror(errno)); + return; + } + + fprintf(stdout, "Intercept verified: %s\n", call); + return; +} + +void +usage(FILE *fp) +{ + fprintf(fp, "Usage: ld-preload-test <Options>\n"); + fprintf(fp, "Options\n"); + fprintf(fp, + "\t--path\t\tPathname is used as the file/directory" + " created for the test.\n"); +} + +int +run_file_tests(char *testfile) +{ + int ret = -1; + struct stat buf; + + assert(testfile); + fprintf(stdout, "Testing creat"); + ret = creat(testfile, S_IRWXU); + check_err(ret, "creat", 2); + + fprintf(stdout, "Testing close"); + ret = close(ret); + check_err(ret, "close", 2); + + fprintf(stdout, "Testing open"); + ret = open(testfile, O_RDONLY); + check_err(ret, "open", 2); + + fprintf(stdout, "Testing read"); + ret = read(0, NULL, 0); + check_err(ret, "read", 2); + + fprintf(stdout, "Testing readv"); + ret = readv(0, NULL, 0); + check_err(ret, "readv", 2); + + fprintf(stdout, "Testing pread"); + ret = pread(0, NULL, 0, 0); + check_err(ret, "pread", 2); + + fprintf(stdout, "Testing write"); + ret = write(0, NULL, 0); + check_err(ret, "write", 2); + + fprintf(stdout, "Testing writev"); + ret = writev(0, NULL, 0); + check_err(ret, "writev", 2); + + fprintf(stdout, "Testing pwrite"); + ret = pwrite(0, NULL, 0, 0); + check_err(ret, "pwrite", 2); + + fprintf(stdout, "Testing lseek"); + ret = lseek(0, 0, 0); + check_err(ret, "lseek", 2); + + fprintf(stdout, "Testing dup"); + ret = dup(0); + check_err(ret, "dup", 2); + + fprintf(stdout, "Testing dup2"); + ret = dup2(0, 0); + check_err(ret, "dup2", 2); + + fprintf(stdout, "Testing fchmod"); + ret = fchmod(0, 0); + check_err(ret, "fchmod", 2); + + fprintf(stdout, "Testing fchown"); + ret = fchown(0, 0, 0); + check_err(ret, "fchown", 2); + + fprintf(stdout, "Testing fsync"); + ret = fsync(0); + check_err(ret, "fsync", 2); + + fprintf(stdout, "Testing ftruncate"); + ret = ftruncate(0, 0); + check_err(ret, "ftruncate", 1); + + fprintf(stdout, "Testing fstat"); + ret = fstat(0, &buf); + check_err(ret, "fstat", 1); + + fprintf(stdout, "Testing sendfile"); + ret = sendfile(0, 0, NULL, 0); + check_err(ret, "sendfile", 1); + + fprintf(stdout, "Testing fcntl"); + ret = fcntl(0, 0, NULL); + check_err(ret, "fcntl", 2); + + fprintf(stdout, "Testing close"); + ret = close(ret); + check_err(ret, "close", 2); + + fprintf(stdout, "Testing remove"); + ret = remove(testfile); + check_err(ret, "remove", 2); + + return ret; +} + +int +run_attr_tests(char *testfile) +{ + int ret = -1; + char *res = NULL; + struct stat buf; + struct statfs sbuf; + struct statvfs svbuf; + + assert(testfile); + + fprintf(stdout, "Testing chmod"); + ret = chmod(testfile, 0); + check_err(ret, "chmod", 2); + + fprintf(stdout, "Testing chown"); + ret = chown(testfile, 0, 0); + check_err(ret, "chown", 2); + + fprintf(stdout, "Testing link"); + ret = link(testfile, testfile); + check_err(ret, "link", 2); + + fprintf(stdout, "Testing rename"); + ret = rename(testfile, testfile); + check_err(ret, "rename", 2); + + fprintf(stdout, "Testing utimes"); + ret = utimes(testfile, NULL); + check_err(ret, "utimes", 2); + + fprintf(stdout, "Testing utime"); + ret = utime(testfile, NULL); + check_err(ret, "utime", 2); + + fprintf(stdout, "Testing unlink"); + ret = unlink(testfile); + check_err(ret, "unlink", 2); + + fprintf(stdout, "Testing symlink"); + ret = symlink(testfile, testfile); + check_err(ret, "symlink", 2); + + fprintf(stdout, "Testing readlink"); + ret = readlink(testfile, testfile, 0); + check_err(ret, "readlink", 2); + + fprintf(stdout, "Testing realpath"); + ret = 0; + res = realpath((const char *)testfile, testfile); + if (!res) + ret = -1; + check_err(ret, "realpath", 2); + + fprintf(stdout, "Testing stat"); + ret = stat(testfile, &buf); + check_err(ret, "stat", 1); + + fprintf(stdout, "Testing lstat"); + ret = lstat(testfile, &buf); + check_err(ret, "lstat", 1); + + fprintf(stdout, "Testing statfs"); + ret = statfs(testfile, &sbuf); + check_err(ret, "statfs", 2); + + fprintf(stdout, "Testing statvfs"); + ret = statvfs(testfile, &svbuf); + check_err(ret, "statvfs", 1); + + fprintf(stdout, "Testing getxattr"); + ret = getxattr(testfile, NULL, NULL, 0); + check_err(ret, "getxattr", 2); + + fprintf(stdout, "Testing lgetxattr"); + ret = lgetxattr(testfile, NULL, NULL, 0); + check_err(ret, "lgetxattr", 1); + + fprintf(stdout, "Testing lchown"); + ret = lchown(testfile, 0, 0); + check_err(ret, "lchown", 2); + return 0; +} + +int +run_dev_tests(char *testfile) +{ + int ret = -1; + + assert(testfile); + + fprintf(stdout, "Testing mknod"); + ret = mknod(testfile, 0, 0); + check_err(ret, "mknod", 2); + + fprintf(stdout, "Testing mkfifo"); + ret = mkfifo(testfile, 0); + check_err(ret, "mkfifo", 2); + return 0; +} + +int +run_dir_tests(char *testpath) +{ + int ret = -1; + DIR *dh = NULL; + struct dirent *dire = NULL; + + assert(testpath); + + fprintf(stdout, "Testing mkdir"); + ret = mkdir(testpath, 0); + check_err(ret, "mkdir", 2); + + fprintf(stdout, "Testing rmdir"); + ret = rmdir(testpath); + check_err(ret, "rmdir", 2); + + fprintf(stdout, "Testing opendir"); + ret = 0; + dh = opendir(testpath); + if (!dh) + ret = -1; + check_err(ret, "opendir", 2); + + fprintf(stdout, "Testing readdir"); + ret = 0; + dire = readdir(dh); + if (!dire) + ret = -1; + check_err(ret, "readdir", 1); + + fprintf(stdout, "Testing readdir_r"); + ret = readdir_r(dh, dire, &dire); + check_err(ret, "readdir_r", 1); + + fprintf(stdout, "Testing rewinddir"); + rewinddir(dh); + check_err(-1, "rewinddir", 1); + + fprintf(stdout, "Testing seekdir"); + seekdir(dh, 0); + check_err(-1, "seekdir", 2); + + fprintf(stdout, "Testing telldir"); + ret = telldir(dh); + check_err(ret, "telldir", 2); + + fprintf(stdout, "Testing closedir"); + ret = closedir(dh); + check_err(ret, "closedir", 2); + return 0; +} + +int +main(int argc, char *argv[]) +{ + char *testpath = NULL; + int x = 0; + + for (; x < argc; ++x) { + if (strcmp(argv[x], "--path") == 0) { + testpath = argv[x + 1]; + continue; + } + } + + if (!testpath) { + fprintf(stderr, "--path not specified\n"); + usage(stderr); + return -1; + } + + run_file_tests(testpath); + run_dir_tests(testpath); + run_attr_tests(testpath); + run_dev_tests(testpath); + + return 0; +} diff --git a/extras/test/ld-preload-test/test-preload.sh b/extras/test/ld-preload-test/test-preload.sh new file mode 100755 index 00000000000..faed5cee345 --- /dev/null +++ b/extras/test/ld-preload-test/test-preload.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +echo "Testing 32-bit offsets build" +LD_PRELOAD="$(pwd)/ld-preload-lib.so" $(pwd)/ld-preload-test32 --path /tmp/testfile +echo +echo "Testing 64-bit offsets build" +LD_PRELOAD="$(pwd)/ld-preload-lib.so" $(pwd)/ld-preload-test64 --path /tmp/testfile diff --git a/extras/test/open-fd-tests.c b/extras/test/open-fd-tests.c new file mode 100644 index 00000000000..509952b4180 --- /dev/null +++ b/extras/test/open-fd-tests.c @@ -0,0 +1,67 @@ + +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/xattr.h> +#include <errno.h> +#include <string.h> + +int +main(int argc, char *argv[]) +{ + int ret = -1; + int fd = 0; + char *filename = NULL; + int loop = 0; + struct stat stbuf = { + 0, + }; + char string[1024] = { + 0, + }; + + if (argc > 1) + filename = argv[1]; + + if (!filename) + filename = "temp-fd-test-file"; + + fd = open(filename, O_RDWR | O_CREAT | O_TRUNC); + if (fd < 0) { + fd = 0; + fprintf(stderr, "open failed : %s\n", strerror(errno)); + goto out; + } + + while (loop < 1000) { + /* Use it as a mechanism to test time delays */ + memset(string, 0, 1024); + scanf("%s", string); + + ret = write(fd, string, strlen(string)); + if (ret != strlen(string)) { + fprintf(stderr, "write failed : %s (%s %d)\n", strerror(errno), + string, loop); + goto out; + } + + ret = write(fd, "\n", 1); + if (ret != 1) { + fprintf(stderr, "write failed : %s (%d)\n", strerror(errno), loop); + goto out; + } + + loop++; + } + + fprintf(stdout, "finishing the test after %d loops\n", loop); + + ret = 0; +out: + if (fd) + close(fd); + + return ret; +} diff --git a/extras/test/run.sh b/extras/test/run.sh new file mode 100755 index 00000000000..4b3839cf679 --- /dev/null +++ b/extras/test/run.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +# Copyright (c) 2006-2012 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. + +# Running gluster sanity test which starts glusterd and runs gluster commands, and exit at the first failure. +$PWD/gluster_commands.sh + +if [ $? -ne 0 ]; then + echo "sanity failed" +else + echo "sanity passed" +fi + +# Stopping glusterd +$PWD/stop_glusterd.sh + diff --git a/extras/test/stop_glusterd.sh b/extras/test/stop_glusterd.sh new file mode 100755 index 00000000000..a2db13f4241 --- /dev/null +++ b/extras/test/stop_glusterd.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# Copyright (c) 2006-2012 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. + +#This script stops the glusterd running on the machine. Helpful for gluster sanity script + +killall -9 glusterd + +if [ $? -ne 0 ]; then + echo "Error: Could not kill glusterd. Either glusterd is not running or kill it manually" +else + echo "Killed glusterd" +fi diff --git a/extras/test/test-ffop.c b/extras/test/test-ffop.c new file mode 100644 index 00000000000..1d9c125db67 --- /dev/null +++ b/extras/test/test-ffop.c @@ -0,0 +1,920 @@ +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/xattr.h> +#include <errno.h> +#include <string.h> +#include <dirent.h> + +int +fd_based_fops_1(char *filename); // for fd based fops after unlink +int +fd_based_fops_2(char *filename); // for fd based fops before unlink +int +dup_fd_based_fops(char *filename); // fops based on fd after dup +int +path_based_fops(char *filename); // for fops based on path +int +dir_based_fops(char *filename); // for fops which operate on directory +int +link_based_fops( + char *filename); // for fops which operate in link files (symlinks) +int +test_open_modes( + char *filename); // to test open syscall with open modes available. +int +generic_open_read_write( + char *filename, + int flag); // generic function which does open write and read. + +int +main(int argc, char *argv[]) +{ + int ret = -1; + char filename[255] = { + 0, + }; + + if (argc > 1) + strcpy(filename, argv[1]); + else + strcpy(filename, "temp-xattr-test-file"); + + ret = fd_based_fops_1(strcat(filename, "_1")); + if (ret < 0) + fprintf(stderr, "fd based file operation 1 failed\n"); + else + fprintf(stdout, "fd based file operation 1 passed\n"); + + ret = fd_based_fops_2(strcat(filename, "_2")); + if (ret < 0) + fprintf(stderr, "fd based file operation 2 failed\n"); + else + fprintf(stdout, "fd based file operation 2 passed\n"); + + ret = dup_fd_based_fops(strcat(filename, "_3")); + if (ret < 0) + fprintf(stderr, "dup fd based file operation failed\n"); + else + fprintf(stdout, "dup fd based file operation passed\n"); + + ret = path_based_fops(strcat(filename, "_4")); + if (ret < 0) + fprintf(stderr, "path based file operation failed\n"); + else + fprintf(stdout, "path based file operation passed\n"); + + ret = dir_based_fops(strcat(filename, "_5")); + if (ret < 0) + fprintf(stderr, "directory based file operation failed\n"); + else + fprintf(stdout, "directory based file operation passed\n"); + + ret = link_based_fops(strcat(filename, "_5")); + if (ret < 0) + fprintf(stderr, "link based file operation failed\n"); + else + fprintf(stdout, "link based file operation passed\n"); + + ret = test_open_modes(strcat(filename, "_5")); + if (ret < 0) + fprintf(stderr, "testing modes of 'open' call failed\n"); + else + fprintf(stdout, "testing modes of 'open' call passed\n"); + +out: + return ret; +} + +int +fd_based_fops_1(char *filename) +{ + int fd = 0; + int ret = -1; + struct stat stbuf = { + 0, + }; + char wstr[50] = { + 0, + }; + char rstr[50] = { + 0, + }; + + fd = open(filename, O_RDWR | O_CREAT); + if (fd < 0) { + fd = 0; + fprintf(stderr, "open failed : %s\n", strerror(errno)); + goto out; + } + + ret = unlink(filename); + if (ret < 0) { + fprintf(stderr, "unlink failed : %s\n", strerror(errno)); + goto out; + } + + strcpy(wstr, "This is my string\n"); + ret = write(fd, wstr, strlen(wstr)); + if (ret <= 0) { + ret = -1; + fprintf(stderr, "write failed: %s\n", strerror(errno)); + goto out; + } + + ret = lseek(fd, 0, SEEK_SET); + if (ret < 0) { + fprintf(stderr, "lseek failed: %s\n", strerror(errno)); + goto out; + } + + ret = read(fd, rstr, strlen(wstr)); + if (ret <= 0) { + ret = -1; + fprintf(stderr, "read failed: %s\n", strerror(errno)); + goto out; + } + + ret = memcmp(rstr, wstr, strlen(wstr)); + if (ret != 0) { + ret = -1; + fprintf(stderr, "read returning junk\n"); + goto out; + } + + ret = ftruncate(fd, 0); + if (ret < 0) { + fprintf(stderr, "ftruncate failed : %s\n", strerror(errno)); + goto out; + } + + ret = fstat(fd, &stbuf); + if (ret < 0) { + fprintf(stderr, "fstat failed : %s\n", strerror(errno)); + goto out; + } + + ret = fchmod(fd, 0640); + if (ret < 0) { + fprintf(stderr, "fchmod failed : %s\n", strerror(errno)); + goto out; + } + + ret = fchown(fd, 10001, 10001); + if (ret < 0) { + fprintf(stderr, "fchown failed : %s\n", strerror(errno)); + goto out; + } + + ret = fsync(fd); + if (ret < 0) { + fprintf(stderr, "fsync failed : %s\n", strerror(errno)); + goto out; + } + + ret = fsetxattr(fd, "trusted.xattr-test", "working", 8, 0); + if (ret < 0) { + fprintf(stderr, "fsetxattr failed : %s\n", strerror(errno)); + goto out; + } + + ret = fdatasync(fd); + if (ret < 0) { + fprintf(stderr, "fdatasync failed : %s\n", strerror(errno)); + goto out; + } + + ret = flistxattr(fd, NULL, 0); + if (ret <= 0) { + ret = -1; + fprintf(stderr, "flistxattr failed : %s\n", strerror(errno)); + goto out; + } + + ret = fgetxattr(fd, "trusted.xattr-test", NULL, 0); + if (ret <= 0) { + ret = -1; + fprintf(stderr, "fgetxattr failed : %s\n", strerror(errno)); + goto out; + } + + ret = fremovexattr(fd, "trusted.xattr-test"); + if (ret < 0) { + fprintf(stderr, "fremovexattr failed : %s\n", strerror(errno)); + goto out; + } + + ret = 0; +out: + if (fd) + close(fd); + + return ret; +} + +int +fd_based_fops_2(char *filename) +{ + int fd = 0; + int ret = -1; + struct stat stbuf = { + 0, + }; + char wstr[50] = { + 0, + }; + char rstr[50] = { + 0, + }; + + fd = open(filename, O_RDWR | O_CREAT); + if (fd < 0) { + fd = 0; + fprintf(stderr, "open failed : %s\n", strerror(errno)); + goto out; + } + + ret = ftruncate(fd, 0); + + if (ret < 0) { + fprintf(stderr, "ftruncate failed : %s\n", strerror(errno)); + goto out; + } + + strcpy(wstr, "This is my second string\n"); + ret = write(fd, wstr, strlen(wstr)); + if (ret < 0) { + ret = -1; + fprintf(stderr, "write failed: %s\n", strerror(errno)); + goto out; + } + + lseek(fd, 0, SEEK_SET); + if (ret < 0) { + fprintf(stderr, "lseek failed: %s\n", strerror(errno)); + goto out; + } + + ret = read(fd, rstr, strlen(wstr)); + if (ret <= 0) { + ret = -1; + fprintf(stderr, "read failed: %s\n", strerror(errno)); + goto out; + } + + ret = memcmp(rstr, wstr, strlen(wstr)); + if (ret != 0) { + ret = -1; + fprintf(stderr, "read returning junk\n"); + goto out; + } + + ret = fstat(fd, &stbuf); + if (ret < 0) { + fprintf(stderr, "fstat failed : %s\n", strerror(errno)); + goto out; + } + + ret = fchmod(fd, 0640); + if (ret < 0) { + fprintf(stderr, "fchmod failed : %s\n", strerror(errno)); + goto out; + } + + ret = fchown(fd, 10001, 10001); + if (ret < 0) { + fprintf(stderr, "fchown failed : %s\n", strerror(errno)); + goto out; + } + + ret = fsync(fd); + if (ret < 0) { + fprintf(stderr, "fsync failed : %s\n", strerror(errno)); + goto out; + } + + ret = fsetxattr(fd, "trusted.xattr-test", "working", 8, 0); + if (ret < 0) { + fprintf(stderr, "fsetxattr failed : %s\n", strerror(errno)); + goto out; + } + + ret = fdatasync(fd); + if (ret < 0) { + fprintf(stderr, "fdatasync failed : %s\n", strerror(errno)); + goto out; + } + + ret = flistxattr(fd, NULL, 0); + if (ret <= 0) { + ret = -1; + fprintf(stderr, "flistxattr failed : %s\n", strerror(errno)); + goto out; + } + + ret = fgetxattr(fd, "trusted.xattr-test", NULL, 0); + if (ret <= 0) { + ret = -1; + fprintf(stderr, "fgetxattr failed : %s\n", strerror(errno)); + goto out; + } + + ret = fremovexattr(fd, "trusted.xattr-test"); + if (ret < 0) { + fprintf(stderr, "fremovexattr failed : %s\n", strerror(errno)); + goto out; + } + +out: + if (fd) + close(fd); + unlink(filename); + + return ret; +} + +int +path_based_fops(char *filename) +{ + int ret = -1; + int fd = 0; + struct stat stbuf = { + 0, + }; + char newfilename[255] = { + 0, + }; + + fd = creat(filename, 0644); + if (fd < 0) { + fprintf(stderr, "creat failed: %s\n", strerror(errno)); + goto out; + } + + ret = truncate(filename, 0); + if (ret < 0) { + fprintf(stderr, "truncate failed: %s\n", strerror(errno)); + goto out; + } + + ret = stat(filename, &stbuf); + if (ret < 0) { + fprintf(stderr, "stat failed: %s\n", strerror(errno)); + goto out; + } + + ret = chmod(filename, 0640); + if (ret < 0) { + fprintf(stderr, "chmod failed: %s\n", strerror(errno)); + goto out; + } + + ret = chown(filename, 10001, 10001); + if (ret < 0) { + fprintf(stderr, "chown failed: %s\n", strerror(errno)); + goto out; + } + + ret = setxattr(filename, "trusted.xattr-test", "working", 8, 0); + if (ret < 0) { + fprintf(stderr, "setxattr failed: %s\n", strerror(errno)); + goto out; + } + + ret = listxattr(filename, NULL, 0); + if (ret <= 0) { + ret = -1; + fprintf(stderr, "listxattr failed: %s\n", strerror(errno)); + goto out; + } + + ret = getxattr(filename, "trusted.xattr-test", NULL, 0); + if (ret <= 0) { + ret = -1; + fprintf(stderr, "getxattr failed: %s\n", strerror(errno)); + goto out; + } + + ret = removexattr(filename, "trusted.xattr-test"); + if (ret < 0) { + fprintf(stderr, "removexattr failed: %s\n", strerror(errno)); + goto out; + } + + ret = access(filename, R_OK | W_OK); + if (ret < 0) { + fprintf(stderr, "access failed: %s\n", strerror(errno)); + goto out; + } + + strcpy(newfilename, filename); + strcat(newfilename, "_new"); + ret = rename(filename, newfilename); + if (ret < 0) { + fprintf(stderr, "rename failed: %s\n", strerror(errno)); + goto out; + } + unlink(newfilename); + +out: + if (fd) + close(fd); + + unlink(filename); + return ret; +} + +int +dup_fd_based_fops(char *filename) +{ + int fd = 0; + int newfd = 0; + int ret = -1; + struct stat stbuf = { + 0, + }; + char wstr[50] = { + 0, + }; + char rstr[50] = { + 0, + }; + + fd = open(filename, O_RDWR | O_CREAT); + if (fd < 0) { + fd = 0; + fprintf(stderr, "open failed : %s\n", strerror(errno)); + goto out; + } + + newfd = dup(fd); + if (newfd < 0) { + ret = -1; + fprintf(stderr, "dup failed: %s\n", strerror(errno)); + goto out; + } + + close(fd); + + strcpy(wstr, "This is my string\n"); + ret = write(newfd, wstr, strlen(wstr)); + if (ret <= 0) { + ret = -1; + fprintf(stderr, "write failed: %s\n", strerror(errno)); + goto out; + } + + ret = lseek(newfd, 0, SEEK_SET); + if (ret < 0) { + fprintf(stderr, "lseek failed: %s\n", strerror(errno)); + goto out; + } + + ret = read(newfd, rstr, strlen(wstr)); + if (ret <= 0) { + ret = -1; + fprintf(stderr, "read failed: %s\n", strerror(errno)); + goto out; + } + + ret = memcmp(rstr, wstr, strlen(wstr)); + if (ret != 0) { + ret = -1; + fprintf(stderr, "read returning junk\n"); + goto out; + } + + ret = ftruncate(newfd, 0); + if (ret < 0) { + fprintf(stderr, "ftruncate failed : %s\n", strerror(errno)); + goto out; + } + + ret = fstat(newfd, &stbuf); + if (ret < 0) { + fprintf(stderr, "fstat failed : %s\n", strerror(errno)); + goto out; + } + + ret = fchmod(newfd, 0640); + if (ret < 0) { + fprintf(stderr, "fchmod failed : %s\n", strerror(errno)); + goto out; + } + + ret = fchown(newfd, 10001, 10001); + if (ret < 0) { + fprintf(stderr, "fchown failed : %s\n", strerror(errno)); + goto out; + } + + ret = fsync(newfd); + if (ret < 0) { + fprintf(stderr, "fsync failed : %s\n", strerror(errno)); + goto out; + } + + ret = fsetxattr(newfd, "trusted.xattr-test", "working", 8, 0); + if (ret < 0) { + fprintf(stderr, "fsetxattr failed : %s\n", strerror(errno)); + goto out; + } + + ret = fdatasync(newfd); + if (ret < 0) { + fprintf(stderr, "fdatasync failed : %s\n", strerror(errno)); + goto out; + } + + ret = flistxattr(newfd, NULL, 0); + if (ret <= 0) { + ret = -1; + fprintf(stderr, "flistxattr failed : %s\n", strerror(errno)); + goto out; + } + + ret = fgetxattr(newfd, "trusted.xattr-test", NULL, 0); + if (ret <= 0) { + ret = -1; + fprintf(stderr, "fgetxattr failed : %s\n", strerror(errno)); + goto out; + } + + ret = fremovexattr(newfd, "trusted.xattr-test"); + if (ret < 0) { + fprintf(stderr, "fremovexattr failed : %s\n", strerror(errno)); + goto out; + } + + ret = 0; +out: + if (newfd) + close(newfd); + ret = unlink(filename); + if (ret < 0) + fprintf(stderr, "unlink failed : %s\n", strerror(errno)); + + return ret; +} + +int +dir_based_fops(char *dirname) +{ + int ret = -1; + DIR *dp = NULL; + char buff[255] = { + 0, + }; + struct dirent *dbuff = { + 0, + }; + struct stat stbuff = { + 0, + }; + char newdname[255] = { + 0, + }; + char *cwd = NULL; + + ret = mkdir(dirname, 0755); + if (ret < 0) { + fprintf(stderr, "mkdir failed: %s\n", strerror(errno)); + goto out; + } + + dp = opendir(dirname); + if (dp == NULL) { + fprintf(stderr, "opendir failed: %s\n", strerror(errno)); + goto out; + } + + dbuff = readdir(dp); + if (NULL == dbuff) { + fprintf(stderr, "readdir failed: %s\n", strerror(errno)); + goto out; + } + + ret = closedir(dp); + if (ret < 0) { + fprintf(stderr, "closedir failed: %s\n", strerror(errno)); + goto out; + } + + ret = stat(dirname, &stbuff); + if (ret < 0) { + fprintf(stderr, "stat failed: %s\n", strerror(errno)); + goto out; + } + + ret = chmod(dirname, 0744); + if (ret < 0) { + fprintf(stderr, "chmod failed: %s\n", strerror(errno)); + goto out; + } + + ret = chown(dirname, 10001, 10001); + if (ret < 0) { + fprintf(stderr, "chmod failed: %s\n", strerror(errno)); + goto out; + } + + ret = setxattr(dirname, "trusted.xattr-test", "working", 8, 0); + if (ret < 0) { + fprintf(stderr, "setxattr failed: %s\n", strerror(errno)); + goto out; + } + + ret = listxattr(dirname, NULL, 0); + if (ret <= 0) { + ret = -1; + fprintf(stderr, "listxattr failed: %s\n", strerror(errno)); + goto out; + } + + ret = getxattr(dirname, "trusted.xattr-test", NULL, 0); + if (ret <= 0) { + ret = -1; + fprintf(stderr, "getxattr failed: %s\n", strerror(errno)); + goto out; + } + + ret = removexattr(dirname, "trusted.xattr-test"); + if (ret < 0) { + fprintf(stderr, "removexattr failed: %s\n", strerror(errno)); + goto out; + } + + strcpy(newdname, dirname); + strcat(newdname, "/../"); + ret = chdir(newdname); + if (ret < 0) { + fprintf(stderr, "chdir failed: %s\n", strerror(errno)); + goto out; + } + + cwd = getcwd(buff, 255); + if (NULL == cwd) { + fprintf(stderr, "getcwd failed: %s\n", strerror(errno)); + goto out; + } + + strcpy(newdname, dirname); + strcat(newdname, "new"); + ret = rename(dirname, newdname); + if (ret < 0) { + fprintf(stderr, "rename failed: %s\n", strerror(errno)); + goto out; + } + + ret = rmdir(newdname); + if (ret < 0) { + fprintf(stderr, "rmdir failed: %s\n", strerror(errno)); + return ret; + } + +out: + rmdir(dirname); + return ret; +} + +int +link_based_fops(char *filename) +{ + int ret = -1; + int fd = 0; + char newname[255] = { + 0, + }; + char linkname[255] = { + 0, + }; + struct stat lstbuf = { + 0, + }; + + fd = creat(filename, 0644); + if (fd < 0) { + fd = 0; + fprintf(stderr, "creat failed: %s\n", strerror(errno)); + goto out; + } + + strcpy(newname, filename); + strcat(newname, "_hlink"); + ret = link(filename, newname); + if (ret < 0) { + fprintf(stderr, "link failed: %s\n", strerror(errno)); + goto out; + } + + ret = unlink(filename); + if (ret < 0) { + fprintf(stderr, "unlink failed: %s\n", strerror(errno)); + goto out; + } + + strcpy(linkname, filename); + strcat(linkname, "_slink"); + ret = symlink(newname, linkname); + if (ret < 0) { + fprintf(stderr, "symlink failed: %s\n", strerror(errno)); + goto out; + } + + ret = lstat(linkname, &lstbuf); + if (ret < 0) { + fprintf(stderr, "lstbuf failed: %s\n", strerror(errno)); + goto out; + } + + ret = lchown(linkname, 10001, 10001); + if (ret < 0) { + fprintf(stderr, "lchown failed: %s\n", strerror(errno)); + goto out; + } + + ret = lsetxattr(linkname, "trusted.lxattr-test", "working", 8, 0); + if (ret < 0) { + fprintf(stderr, "lsetxattr failed: %s\n", strerror(errno)); + goto out; + } + + ret = llistxattr(linkname, NULL, 0); + if (ret < 0) { + ret = -1; + fprintf(stderr, "llistxattr failed: %s\n", strerror(errno)); + goto out; + } + + ret = lgetxattr(linkname, "trusted.lxattr-test", NULL, 0); + if (ret < 0) { + ret = -1; + fprintf(stderr, "lgetxattr failed: %s\n", strerror(errno)); + goto out; + } + + ret = lremovexattr(linkname, "trusted.lxattr-test"); + if (ret < 0) { + fprintf(stderr, "lremovexattr failed: %s\n", strerror(errno)); + goto out; + } + +out: + if (fd) + close(fd); + unlink(linkname); + unlink(newname); +} + +int +test_open_modes(char *filename) +{ + int ret = -1; + + ret = generic_open_read_write(filename, O_CREAT | O_WRONLY); + if (3 != ret) { + fprintf(stderr, "flag O_CREAT|O_WRONLY failed: \n"); + goto out; + } + + ret = generic_open_read_write(filename, O_CREAT | O_RDWR); + if (ret != 0) { + fprintf(stderr, "flag O_CREAT|O_RDWR failed\n"); + goto out; + } + + ret = generic_open_read_write(filename, O_CREAT | O_RDONLY); + if (ret != 0) { + fprintf(stderr, "flag O_CREAT|O_RDONLY failed\n"); + goto out; + } + + ret = creat(filename, 0644); + close(ret); + ret = generic_open_read_write(filename, O_WRONLY); + if (3 != ret) { + fprintf(stderr, "flag O_WRONLY failed\n"); + goto out; + } + + ret = creat(filename, 0644); + close(ret); + ret = generic_open_read_write(filename, O_RDWR); + if (0 != ret) { + fprintf(stderr, "flag O_RDWR failed\n"); + goto out; + } + + ret = creat(filename, 0644); + close(ret); + ret = generic_open_read_write(filename, O_RDONLY); + if (0 != ret) { + fprintf(stderr, "flag O_RDONLY failed\n"); + goto out; + } + + ret = creat(filename, 0644); + close(ret); + ret = generic_open_read_write(filename, O_TRUNC | O_WRONLY); + if (3 != ret) { + fprintf(stderr, "flag O_TRUNC|O_WRONLY failed\n"); + goto out; + } + +#if 0 /* undefined behaviour, unable to reliably test */ + ret = creat (filename, 0644); + close (ret); + ret = generic_open_read_write (filename, O_TRUNC|O_RDONLY); + if (0 != ret) { + fprintf (stderr, "flag O_TRUNC|O_RDONLY failed\n"); + goto out; + } +#endif + + ret = generic_open_read_write(filename, O_CREAT | O_RDWR | O_SYNC); + if (0 != ret) { + fprintf(stderr, "flag O_CREAT|O_RDWR|O_SYNC failed\n"); + goto out; + } + + ret = creat(filename, 0644); + close(ret); + ret = generic_open_read_write(filename, O_CREAT | O_EXCL); + if (0 != ret) { + fprintf(stderr, "flag O_CREAT|O_EXCL failed\n"); + goto out; + } + +out: + return ret; +} + +int +generic_open_read_write(char *filename, int flag) +{ + int fd = 0; + int ret = -1; + char wstring[50] = { + 0, + }; + char rstring[50] = { + 0, + }; + + fd = open(filename, flag); + if (fd < 0) { + if (flag == O_CREAT | O_EXCL && errno == EEXIST) { + unlink(filename); + return 0; + } else { + fd = 0; + fprintf(stderr, "open failed: %s\n", strerror(errno)); + return 1; + } + } + + strcpy(wstring, "My string to write\n"); + ret = write(fd, wstring, strlen(wstring)); + if (ret <= 0) { + if (errno != EBADF) { + fprintf(stderr, "write failed: %s\n", strerror(errno)); + close(fd); + unlink(filename); + return 2; + } + } + + ret = lseek(fd, 0, SEEK_SET); + if (ret < 0) { + close(fd); + unlink(filename); + return 4; + } + + ret = read(fd, rstring, strlen(wstring)); + if (ret < 0) { + close(fd); + unlink(filename); + return 3; + } + + /* Compare the rstring with wstring. But we do not want to return + * error when the flag is either O_RDONLY, O_CREAT|O_RDONLY or + * O_TRUNC|O_RDONLY. Because in that case we are not writing + * anything to the file.*/ + + ret = memcmp(wstring, rstring, strlen(wstring)); + if (0 != ret && !(flag == O_CREAT | O_RDONLY || flag == O_RDONLY || + flag == O_TRUNC | O_RDONLY)) { + fprintf(stderr, "read is returning junk\n"); + close(fd); + unlink(filename); + return 4; + } + + close(fd); + unlink(filename); + return 0; +} |
