/* Copyright (c) 2007-2009 Gluster, Inc. This file is part of GlusterFS. GlusterFS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. GlusterFS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define PRELOAD_ERRNO_VERF 6449 inline 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 \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; }