Add the ZFS Test Suite

Add the ZFS Test Suite and test-runner framework from illumos.
This is a continuation of the work done by Turbo Fredriksson to
port the ZFS Test Suite to Linux.  While this work was originally
conceived as a stand alone project integrating it directly with
the ZoL source tree has several advantages:

  * Allows the ZFS Test Suite to be packaged in zfs-test package.
    * Facilitates easy integration with the CI testing.
    * Users can locally run the ZFS Test Suite to validate ZFS.
      This testing should ONLY be done on a dedicated test system
      because the ZFS Test Suite in its current form is destructive.
  * Allows the ZFS Test Suite to be run directly in the ZoL source
    tree enabled developers to iterate quickly during development.
  * Developers can easily add/modify tests in the framework as
    features are added or functionality is changed.  The tests
    will then always be in sync with the implementation.

Full documentation for how to run the ZFS Test Suite is available
in the tests/README.md file.

Warning: This test suite is designed to be run on a dedicated test
system.  It will make modifications to the system including, but
not limited to, the following.

  * Adding new users
  * Adding new groups
  * Modifying the following /proc files:
    * /proc/sys/kernel/core_pattern
    * /proc/sys/kernel/core_uses_pid
  * Creating directories under /

Notes:
  * Not all of the test cases are expected to pass and by default
    these test cases are disabled.  The failures are primarily due
    to assumption made for illumos which are invalid under Linux.
  * When updating these test cases it should be done in as generic
    a way as possible so the patch can be submitted back upstream.
    Most existing library functions have been updated to be Linux
    aware, and the following functions and variables have been added.
    * Functions:
      * is_linux          - Used to wrap a Linux specific section.
      * block_device_wait - Waits for block devices to be added to /dev/.
    * Variables:            Linux          Illumos
      * ZVOL_DEVDIR         "/dev/zvol"    "/dev/zvol/dsk"
      * ZVOL_RDEVDIR        "/dev/zvol"    "/dev/zvol/rdsk"
      * DEV_DSKDIR          "/dev"         "/dev/dsk"
      * DEV_RDSKDIR         "/dev"         "/dev/rdsk"
      * NEWFS_DEFAULT_FS    "ext2"         "ufs"
  * Many of the disabled test cases fail because 'zfs/zpool destroy'
    returns EBUSY.  This is largely causes by the asynchronous nature
    of device handling on Linux and is expected, the impacted test
    cases will need to be updated to handle this.
  * There are several test cases which have been disabled because
    they can trigger a deadlock.  A primary example of this is to
    recursively create zpools within zpools.  These tests have been
    disabled until the root issue can be addressed.
  * Illumos specific utilities such as (mkfile) should be added to
    the tests/zfs-tests/cmd/ directory.  Custom programs required by
    the test scripts can also be added here.
  * SELinux should be either is permissive mode or disabled when
    running the tests.  The test cases should be updated to conform
    to a standard policy.
  * Redundant test functionality has been removed (zfault.sh).
  * Existing test scripts (zconfig.sh) should be migrated to use
    the framework for consistency and ease of testing.
  * The DISKS environment variable currently only supports loopback
    devices because of how the ZFS Test Suite expects partitions to
    be named (p1, p2, etc).  Support must be added to generate the
    correct partition name based on the device location and name.
  * The ZFS Test Suite is part of the illumos code base at:
    https://github.com/illumos/illumos-gate/tree/master/usr/src/test

Original-patch-by: Turbo Fredriksson <turbo@bayour.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
Closes #6
Closes #1534
This commit is contained in:
Brian Behlendorf
2015-07-01 15:23:09 -07:00
parent 887d1e60ef
commit 6bb24f4dc7
1243 changed files with 89497 additions and 1042 deletions
+1
View File
@@ -0,0 +1 @@
SUBDIRS = cmd include tests
+22
View File
@@ -0,0 +1,22 @@
EXTRA_DIST = file_common.h
SUBDIRS = \
chg_usr_exec \
devname2devid \
dir_rd_update \
file_check \
file_trunc \
file_write \
largest_file \
mkbusy \
mkfile \
mkfiles \
mktree \
mmap_exec \
mmapwrite \
randfree_file \
readmmap \
rename_dir \
rm_lnkcnt_zero_file \
threadsappend \
xattrtest
@@ -0,0 +1 @@
/chg_usr_exec
@@ -0,0 +1,6 @@
include $(top_srcdir)/config/Rules.am
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
pkgexec_PROGRAMS = chg_usr_exec
chg_usr_exec_SOURCES = chg_usr_exec.c
@@ -0,0 +1,77 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <pwd.h>
#define EXECSHELL "/bin/sh"
int
main(int argc, char *argv[])
{
char *plogin = NULL;
char cmds[BUFSIZ] = { 0 };
char sep[] = " ";
struct passwd *ppw = NULL;
int i, len;
if (argc < 3 || strlen(argv[1]) == 0) {
(void) printf("\tUsage: %s <login> <commands> ...\n", argv[0]);
return (1);
}
plogin = argv[1];
len = 0;
for (i = 2; i < argc; i++) {
(void) snprintf(cmds+len, sizeof (cmds)-len,
"%s%s", argv[i], sep);
len += strlen(argv[i]) + strlen(sep);
}
if ((ppw = getpwnam(plogin)) == NULL) {
perror("getpwnam");
return (errno);
}
if (setgid(ppw->pw_gid) != 0) {
perror("setgid");
return (errno);
}
if (setuid(ppw->pw_uid) != 0) {
perror("setuid");
return (errno);
}
if (execl(EXECSHELL, "sh", "-c", cmds, (char *)NULL) != 0) {
perror("execl: " EXECSHELL);
return (errno);
}
return (0);
}
@@ -0,0 +1 @@
/devname2devid
@@ -0,0 +1,7 @@
include $(top_srcdir)/config/Rules.am
pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/bin
# DISABLED: Not supported under Linux
# pkgdata_PROGRAMS = devname2devid
# devname2devid_SOURCES = devname2devid.c
@@ -0,0 +1,120 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <devid.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
/*
* Usage: devname2devid <devicepath>
*
* Examples:
* # ./devname2devid /dev/dsk/c1t4d0s0
* devid id1,sd@SSEAGATE_ST318404LSUN18G_3BT2G0Z300002146G4CR/a
* # ./devname2devid /dev/dsk/c1t4d0
* devid id1,sd@SSEAGATE_ST318404LSUN18G_3BT2G0Z300002146G4CR/wd
* # ./devname2devid /dev/dsk/c1t4d0s1
* devid id1,sd@SSEAGATE_ST318404LSUN18G_3BT2G0Z300002146G4CR/b
* #
*
* This program accepts a disk or disk slice path and prints a
* device id.
*
* Exit values:
* 0 - means success
* 1 - means failure
*
*/
int
main(int argc, char *argv[])
{
int fd;
ddi_devid_t devid;
char *minor_name, *devidstr, *device;
#ifdef DEBUG
devid_nmlist_t *list = NULL;
char *search_path;
int i;
#endif
if (argc == 1) {
(void) printf("%s <devicepath> [search path]\n",
argv[0]);
exit(1);
}
device = argv[1];
if ((fd = open(device, O_RDONLY|O_NDELAY)) < 0) {
perror(device);
exit(1);
}
if (devid_get(fd, &devid) != 0) {
perror("devid_get");
exit(1);
}
if (devid_get_minor_name(fd, &minor_name) != 0) {
perror("devid_get_minor_name");
exit(1);
}
if ((devidstr = devid_str_encode(devid, minor_name)) == 0) {
perror("devid_str_encode");
exit(1);
}
(void) printf("devid %s\n", devidstr);
devid_str_free(devidstr);
#ifdef DEBUG
if (argc == 3) {
search_path = argv[2];
} else {
search_path = "/dev/rdsk";
}
if (devid_deviceid_to_nmlist(search_path, devid, DEVID_MINOR_NAME_ALL,
&list)) {
perror("devid_deviceid_to_nmlist");
exit(1);
}
/* loop through list and process device names and numbers */
for (i = 0; list[i].devname != NULL; i++) {
(void) printf("devname: %s %p\n", list[i].devname, list[i].dev);
}
devid_free_nmlist(list);
#endif /* DEBUG */
devid_str_free(minor_name);
devid_free(devid);
return (0);
}
@@ -0,0 +1 @@
/dir_rd_update
@@ -0,0 +1,6 @@
include $(top_srcdir)/config/Rules.am
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
pkgexec_PROGRAMS = dir_rd_update
dir_rd_update_SOURCES = dir_rd_update.c
@@ -0,0 +1,117 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Assertion:
*
* A read operation and directory update operation performed
* concurrently on the same directory can lead to deadlock
* on a UFS logging file system, but not on a ZFS file system.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define TMP_DIR /tmp
static char dirpath[256];
int
main(int argc, char **argv)
{
char *cp1 = "";
int i = 0;
int ret = 0;
int testdd = 0;
pid_t pid;
static const int op_num = 5;
if (argc == 1) {
(void) printf("Usage: %s <mount point>\n", argv[0]);
exit(-1);
}
for (i = 0; i < 256; i++) {
dirpath[i] = 0;
}
cp1 = argv[1];
(void) strcpy(&dirpath[0], (const char *)cp1);
(void) strcat(&dirpath[strlen(dirpath)], "TMP_DIR");
ret = mkdir(dirpath, 0777);
if (ret != 0) {
if (errno != EEXIST) {
(void) printf("%s: mkdir(<%s>, 0777) failed: errno "
"(decimal)=%d\n", argv[0], dirpath, errno);
exit(-1);
}
}
testdd = open(dirpath, O_RDONLY|O_RSYNC|O_SYNC|O_DSYNC);
if (testdd < 0) {
(void) printf("%s: open(<%s>, O_RDONLY|O_RSYNC|O_SYNC|O_DSYNC)"
" failed: errno (decimal)=%d\n", argv[0], dirpath, errno);
exit(-1);
} else {
(void) close(testdd);
}
pid = fork();
if (pid > 0) {
int fd = open(dirpath, O_RDONLY|O_RSYNC|O_SYNC|O_DSYNC);
char buf[16];
int rdret;
int j = 0;
while (j < op_num) {
(void) sleep(1);
rdret = read(fd, buf, 16);
if (rdret == -1) {
(void) printf("readdir failed");
}
j++;
}
} else if (pid == 0) {
int fd = open(dirpath, O_RDONLY);
int chownret;
int k = 0;
while (k < op_num) {
(void) sleep(1);
chownret = fchown(fd, 0, 0);
if (chownret == -1) {
(void) printf("chown failed");
}
k++;
}
}
return (0);
}
@@ -0,0 +1 @@
/file_check
@@ -0,0 +1,6 @@
include $(top_srcdir)/config/Rules.am
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
pkgexec_PROGRAMS = file_check
file_check_SOURCES = file_check.c
@@ -0,0 +1,86 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include "../file_common.h"
static unsigned char bigbuffer[BIGBUFFERSIZE];
/*
* Given a filename, check that the file consists entirely
* of a particular pattern. If the pattern is not specified a
* default will be used. For default values see file_common.h
*/
int
main(int argc, char **argv)
{
int bigfd;
long i, n;
unsigned char fillchar = DATA;
int bigbuffersize = BIGBUFFERSIZE;
int64_t read_count = 0;
/*
* Validate arguments
*/
if (argc < 2) {
(void) printf("Usage: %s filename [pattern]\n",
argv[0]);
exit(1);
}
if (argv[2]) {
fillchar = atoi(argv[2]);
}
/*
* Read the file contents and check every character
* against the supplied pattern. Abort if the
* pattern check fails.
*/
if ((bigfd = open(argv[1], O_RDONLY)) == -1) {
(void) printf("open %s failed %d\n", argv[1], errno);
exit(1);
}
do {
if ((n = read(bigfd, &bigbuffer, bigbuffersize)) == -1) {
(void) printf("read failed (%ld), %d\n", n, errno);
exit(errno);
}
for (i = 0; i < n; i++) {
if (bigbuffer[i] != fillchar) {
(void) printf("error %s: 0x%x != 0x%x)\n",
argv[1], bigbuffer[i], fillchar);
exit(1);
}
}
read_count += n;
} while (n == bigbuffersize);
return (0);
}
+62
View File
@@ -0,0 +1,62 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef FILE_COMMON_H
#define FILE_COMMON_H
/*
* header file for file_* utilities. These utilities
* are used by the test cases to perform various file
* operations (append writes, for example).
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <strings.h>
#define BLOCKSZ 8192
#define DATA 0xa5
#define DATA_RANGE 120
#define BIGBUFFERSIZE 0x800000
#define BIGFILESIZE 20
extern char *optarg;
extern int optind, opterr, optopt;
#ifdef __cplusplus
}
#endif
#endif /* FILE_COMMON_H */
@@ -0,0 +1 @@
/file_trunc
@@ -0,0 +1,6 @@
include $(top_srcdir)/config/Rules.am
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
pkgexec_PROGRAMS = file_trunc
file_trunc_SOURCES = file_trunc.c
+244
View File
@@ -0,0 +1,244 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <sys/param.h>
#include <string.h>
#include <time.h>
#include <inttypes.h>
#define FSIZE 256*1024*1024
#define BSIZE 512
/* Initialize Globals */
static long fsize = FSIZE;
static size_t bsize = BSIZE;
static int count = 0;
static int rflag = 0;
static int seed = 0;
static int vflag = 0;
static int errflag = 0;
static off_t offset = 0;
static char *filename = NULL;
static void usage(char *execname);
static void parse_options(int argc, char *argv[]);
static void do_write(int fd);
static void do_trunc(int fd);
static void
usage(char *execname)
{
(void) fprintf(stderr,
"usage: %s [-b blocksize] [-c count] [-f filesize]"
" [-o offset] [-s seed] [-r] [-v] filename\n", execname);
(void) exit(1);
}
int
main(int argc, char *argv[])
{
int i = 0;
int fd = -1;
parse_options(argc, argv);
fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666);
if (fd < 0) {
perror("open");
exit(3);
}
while (i < count) {
(void) do_write(fd);
(void) do_trunc(fd);
i++;
}
(void) close(fd);
return (0);
}
static void
parse_options(int argc, char *argv[])
{
int c;
extern char *optarg;
extern int optind, optopt;
count = fsize / bsize;
seed = time(NULL);
while ((c = getopt(argc, argv, "b:c:f:o:rs:v")) != -1) {
switch (c) {
case 'b':
bsize = atoi(optarg);
break;
case 'c':
count = atoi(optarg);
break;
case 'f':
fsize = atoi(optarg);
break;
case 'o':
offset = atoi(optarg);
break;
case 'r':
rflag++;
break;
case 's':
seed = atoi(optarg);
break;
case 'v':
vflag++;
break;
case ':':
(void) fprintf(stderr,
"Option -%c requires an operand\n", optopt);
errflag++;
break;
case '?':
(void) fprintf(stderr,
"Unrecognized option: -%c\n", optopt);
errflag++;
break;
}
if (errflag) {
(void) usage(argv[0]);
}
}
if (argc <= optind) {
(void) fprintf(stderr,
"No filename specified\n");
usage(argv[0]);
}
filename = argv[optind];
if (vflag) {
(void) fprintf(stderr, "Seed = %d\n", seed);
}
srandom(seed);
}
static void
do_write(int fd)
{
off_t roffset = 0;
char *buf = NULL;
char *rbuf = NULL;
buf = (char *)calloc(1, bsize);
rbuf = (char *)calloc(1, bsize);
if (buf == NULL || rbuf == NULL) {
perror("malloc");
exit(4);
}
roffset = random() % fsize;
if (lseek64(fd, (offset + roffset), SEEK_SET) < 0) {
perror("lseek");
exit(5);
}
strcpy(buf, "ZFS Test Suite Truncation Test");
if (write(fd, buf, bsize) < bsize) {
perror("write");
exit(6);
}
if (rflag) {
if (lseek64(fd, (offset + roffset), SEEK_SET) < 0) {
perror("lseek");
exit(7);
}
if (read(fd, rbuf, bsize) < bsize) {
perror("read");
exit(8);
}
if (memcmp(buf, rbuf, bsize) != 0) {
perror("memcmp");
exit(9);
}
}
if (vflag) {
(void) fprintf(stderr,
"Wrote to offset %" PRId64 "\n", (offset + roffset));
if (rflag) {
(void) fprintf(stderr,
"Read back from offset %" PRId64 "\n",
(offset + roffset));
}
}
(void) free(buf);
(void) free(rbuf);
}
static void
do_trunc(int fd)
{
off_t roffset = 0;
roffset = random() % fsize;
if (ftruncate64(fd, (offset + roffset)) < 0) {
perror("truncate");
exit(7);
}
if (vflag) {
(void) fprintf(stderr, "Truncated at offset %" PRId64 "\n",
(offset + roffset));
}
}
@@ -0,0 +1 @@
/file_write
@@ -0,0 +1,6 @@
include $(top_srcdir)/config/Rules.am
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
pkgexec_PROGRAMS = file_write
file_write_SOURCES = file_write.c
+229
View File
@@ -0,0 +1,229 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include "../file_common.h"
#include <libgen.h>
#include <string.h>
#include <inttypes.h>
#include <sys/types.h>
#include <unistd.h>
typedef unsigned char uchar_t;
typedef long long longlong_t;
typedef longlong_t offset_t;
static unsigned char bigbuffer[BIGBUFFERSIZE];
/*
* Writes (or appends) a given value to a file repeatedly.
* See header file for defaults.
*/
static void usage(char *);
int
main(int argc, char **argv)
{
int bigfd;
int c;
int oflag = 0;
int err = 0;
int k;
long i;
int64_t good_writes = 0;
uchar_t nxtfillchar;
char *prog = argv[0];
/*
* Default Parameters
*/
int write_count = BIGFILESIZE;
uchar_t fillchar = DATA;
int block_size = BLOCKSZ;
char *filename = NULL;
char *operation = NULL;
offset_t noffset, offset = 0;
int verbose = 0;
int rsync = 0;
int wsync = 0;
/*
* Process Arguments
*/
while ((c = getopt(argc, argv, "b:c:d:s:f:o:vwr")) != -1) {
switch (c) {
case 'b':
block_size = atoi(optarg);
break;
case 'c':
write_count = atoi(optarg);
break;
case 'd':
fillchar = atoi(optarg);
break;
case 's':
offset = atoll(optarg);
break;
case 'f':
filename = optarg;
break;
case 'o':
operation = optarg;
break;
case 'v':
verbose = 1;
break;
case 'w':
wsync = 1;
break;
case 'r':
rsync = 1;
break;
case '?':
(void) printf("unknown arg %c\n", optopt);
usage(prog);
break;
}
}
/*
* Validate Parameters
*/
if (!filename) {
(void) printf("Filename not specified (-f <file>)\n");
err++;
}
if (!operation) {
(void) printf("Operation not specified (-o <operation>).\n");
err++;
}
if (block_size > BIGBUFFERSIZE) {
(void) printf("block_size is too large max==%d.\n",
BIGBUFFERSIZE);
err++;
}
if (err) usage(prog);
/*
* Prepare the buffer and determine the requested operation
*/
nxtfillchar = fillchar;
k = 0;
for (i = 0; i < block_size; i++) {
bigbuffer[i] = nxtfillchar;
if (fillchar == 0) {
if ((k % DATA_RANGE) == 0) {
k = 0;
}
nxtfillchar = k++;
}
}
/*
* using the strncmp of operation will make the operation match the
* first shortest match - as the operations are unique from the first
* character this means that we match single character operations
*/
if ((strncmp(operation, "create", strlen(operation) + 1)) == 0 ||
(strncmp(operation, "overwrite", strlen(operation) + 1)) == 0) {
oflag = (O_RDWR|O_CREAT);
} else if ((strncmp(operation, "append", strlen(operation) + 1)) == 0) {
oflag = (O_RDWR|O_APPEND);
} else {
(void) printf("valid operations are <create|append> not '%s'\n",
operation);
usage(prog);
}
if (rsync) {
oflag = oflag | O_RSYNC;
}
if (wsync) {
oflag = oflag | O_SYNC;
}
/*
* Given an operation (create/overwrite/append), open the file
* accordingly and perform a write of the appropriate type.
*/
if ((bigfd = open(filename, oflag, 0666)) == -1) {
(void) printf("open %s: failed [%s]%d. Aborting!\n", filename,
strerror(errno), errno);
exit(errno);
}
noffset = lseek64(bigfd, offset, SEEK_SET);
if (noffset != offset) {
(void) printf("llseek %s (%lld/%lld) failed [%s]%d.Aborting!\n",
filename, offset, noffset, strerror(errno), errno);
exit(errno);
}
if (verbose) {
(void) printf("%s: block_size = %d, write_count = %d, "
"offset = %lld, data = %s%d\n", filename, block_size,
write_count, offset,
(fillchar == 0) ? "0->" : "",
(fillchar == 0) ? DATA_RANGE : fillchar);
}
for (i = 0; i < write_count; i++) {
ssize_t n;
if ((n = write(bigfd, &bigbuffer, block_size)) == -1) {
(void) printf("write failed (%ld), good_writes = %"
PRId64 ", " "error: %s[%d]\n",
(long)n, good_writes,
strerror(errno),
errno);
exit(errno);
}
good_writes++;
}
if (verbose) {
(void) printf("Success: good_writes = %" PRId64 "(%"
PRId64 ")\n", good_writes, (good_writes * block_size));
}
return (0);
}
static void
usage(char *prog)
{
(void) printf("Usage: %s [-v] -o {create,overwrite,append} -f file_name"
" [-b block_size]\n"
"\t[-s offset] [-c write_count] [-d data]\n"
"\twhere [data] equal to zero causes chars "
"0->%d to be repeated throughout\n", prog, DATA_RANGE);
exit(1);
}
@@ -0,0 +1 @@
/largest_file
@@ -0,0 +1,6 @@
include $(top_srcdir)/config/Rules.am
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
pkgexec_PROGRAMS = largest_file
largest_file_SOURCES = largest_file.c
@@ -0,0 +1,140 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include "../file_common.h"
#include <sys/param.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
typedef long long offset_t;
#define MAXOFFSET_T LLONG_MAX
/*
* --------------------------------------------------------------
*
* Assertion:
* The last byte of the largest file size can be
* accessed without any errors. Also, the writing
* beyond the last byte of the largest file size
* will produce an errno of EFBIG.
*
* --------------------------------------------------------------
* If the write() system call below returns a "1",
* then the last byte can be accessed.
* --------------------------------------------------------------
*/
static void sigxfsz(int);
static void usage(char *);
int
main(int argc, char **argv)
{
int fd = 0;
offset_t offset = (MAXOFFSET_T - 1);
offset_t llseek_ret = 0;
int write_ret = 0;
int err = 0;
char mybuf[5];
char *testfile;
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
if (argc != 2) {
usage(argv[0]);
}
(void) sigset(SIGXFSZ, sigxfsz);
testfile = strdup(argv[1]);
fd = open(testfile, O_CREAT | O_RDWR, mode);
if (fd < 0) {
perror("Failed to create testfile");
err = errno;
goto out;
}
llseek_ret = lseek64(fd, offset, SEEK_SET);
if (llseek_ret < 0) {
perror("Failed to seek to end of testfile");
err = errno;
goto out;
}
write_ret = write(fd, mybuf, 1);
if (write_ret < 0) {
perror("Failed to write to end of file");
err = errno;
goto out;
}
offset = 0;
llseek_ret = lseek64(fd, offset, SEEK_CUR);
if (llseek_ret < 0) {
perror("Failed to seek to end of file");
err = errno;
goto out;
}
write_ret = write(fd, mybuf, 1);
if (write_ret < 0) {
if (errno == EFBIG) {
(void) printf("write errno=EFBIG: success\n");
err = 0;
} else {
perror("Did not receive EFBIG");
err = errno;
}
} else {
(void) printf("write completed successfully, test failed\n");
err = 1;
}
out:
(void) unlink(testfile);
free(testfile);
return (err);
}
static void
usage(char *name)
{
(void) printf("%s <testfile>\n", name);
exit(1);
}
/* ARGSUSED */
static void
sigxfsz(int signo)
{
(void) printf("\nlargest_file: sigxfsz() caught SIGXFSZ\n");
}
+1
View File
@@ -0,0 +1 @@
/mkbusy
+6
View File
@@ -0,0 +1,6 @@
include $(top_srcdir)/config/Rules.am
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
pkgexec_PROGRAMS = mkbusy
mkbusy_SOURCES = mkbusy.c
+183
View File
@@ -0,0 +1,183 @@
/*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*/
/*
* Copyright (c) 2012 by Delphix. All rights reserved.
*/
/*
* Make a directory busy. If the argument is an existing file or directory,
* simply open it directly and pause. If not, verify that the parent directory
* exists, and create a new file in that directory.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <strings.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
typedef enum boolean { B_FALSE, B_TRUE } boolean_t;
static void
usage(char *progname)
{
(void) fprintf(stderr, "Usage: %s <dirname|filename>\n", progname);
exit(1);
}
static void
fail(char *err, int rval)
{
perror(err);
exit(rval);
}
static void
daemonize(void)
{
pid_t pid;
if ((pid = fork()) < 0) {
fail("fork", 1);
} else if (pid != 0) {
(void) fprintf(stdout, "%ld\n", (long)pid);
exit(0);
}
(void) setsid();
(void) close(0);
(void) close(1);
(void) close(2);
}
int
main(int argc, char *argv[])
{
int ret, c;
boolean_t isdir = B_FALSE;
boolean_t fflag = B_FALSE;
boolean_t rflag = B_FALSE;
struct stat sbuf;
char *fpath = NULL;
char *prog = argv[0];
while ((c = getopt(argc, argv, "fr")) != -1) {
switch (c) {
/* Open the file or directory read only */
case 'r':
rflag = B_TRUE;
break;
/* Run in the foreground */
case 'f':
fflag = B_TRUE;
break;
default:
usage(prog);
}
}
argc -= optind;
argv += optind;
if (argc != 1)
usage(prog);
if ((ret = stat(argv[0], &sbuf)) != 0) {
char *arg, *dname, *fname;
int arglen, dlen, flen;
char *slash;
/*
* The argument supplied doesn't exist. Copy the path, and
* remove the trailing slash if presnt.
*/
if ((arg = strdup(argv[0])) == NULL)
fail("strdup", 1);
arglen = strlen(arg);
if (arg[arglen - 1] == '/')
arg[arglen - 1] = '\0';
/*
* Get the directory and file names, using the current directory
* if the provided path doesn't specify a directory at all.
*/
if ((slash = strrchr(arg, '/')) == NULL) {
dname = strdup(".");
fname = strdup(arg);
} else {
*slash = '\0';
dname = strdup(arg);
fname = strdup(slash + 1);
}
free(arg);
if (dname == NULL || fname == NULL)
fail("strdup", 1);
dlen = strlen(dname);
flen = strlen(fname);
/* The directory portion of the path must exist */
if ((ret = stat(dname, &sbuf)) != 0 || !(sbuf.st_mode &
S_IFDIR))
usage(prog);
if ((fpath = (char *)malloc(dlen + 1 + flen + 1)) == NULL)
fail("malloc", 1);
(void) memset(fpath, '\0', dlen + 1 + flen + 1);
(void) strncpy(fpath, dname, dlen);
fpath[dlen] = '/';
(void) strncat(fpath, fname, flen);
free(dname);
free(fname);
} else if ((sbuf.st_mode & S_IFMT) == S_IFREG ||
(sbuf.st_mode & S_IFMT) == S_IFLNK ||
(sbuf.st_mode & S_IFMT) == S_IFCHR ||
(sbuf.st_mode & S_IFMT) == S_IFBLK) {
fpath = strdup(argv[0]);
} else if ((sbuf.st_mode & S_IFMT) == S_IFDIR) {
fpath = strdup(argv[0]);
isdir = B_TRUE;
} else {
usage(prog);
}
if (fpath == NULL)
fail("strdup", 1);
if (isdir == B_FALSE) {
int fd, flags;
mode_t mode = S_IRUSR | S_IWUSR;
flags = rflag == B_FALSE ? O_CREAT | O_RDWR : O_RDONLY;
if ((fd = open(fpath, flags, mode)) < 0)
fail("open", 1);
} else {
DIR *dp;
if ((dp = opendir(fpath)) == NULL)
fail("opendir", 1);
}
free(fpath);
if (fflag == B_FALSE)
daemonize();
(void) pause();
/* NOTREACHED */
return (0);
}
+1
View File
@@ -0,0 +1 @@
/mkfile
+6
View File
@@ -0,0 +1,6 @@
include $(top_srcdir)/config/Rules.am
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
pkgexec_PROGRAMS = mkfile
mkfile_SOURCES = mkfile.c
+275
View File
@@ -0,0 +1,275 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <libintl.h>
#include <errno.h>
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define BLOCK_SIZE 512 /* bytes */
#define KILOBYTE 1024
#define MEGABYTE (KILOBYTE * KILOBYTE)
#define GIGABYTE (KILOBYTE * MEGABYTE)
#define FILE_MODE (S_ISVTX + S_IRUSR + S_IWUSR)
typedef long long offset_t;
static void usage(void);
int
main(int argc, char **argv)
{
char *opts;
off_t size;
size_t len;
size_t mult = 1;
char *buf = NULL;
size_t bufsz = 0;
int errors = 0;
int i;
int verbose = 0; /* option variable */
int nobytes = 0; /* option variable */
int saverr;
if (argc == 1)
usage();
while (argv[1] && argv[1][0] == '-') {
opts = &argv[1][0];
while (*(++opts)) {
switch (*opts) {
case 'v':
verbose++;
break;
case 'n':
nobytes++;
break;
default:
usage();
}
}
argc--;
argv++;
}
if (argc < 3)
usage();
len = strlen(argv[1]);
if (len && isalpha(argv[1][len-1])) {
switch (argv[1][len-1]) {
case 'k':
case 'K':
mult = KILOBYTE;
break;
case 'b':
case 'B':
mult = BLOCK_SIZE;
break;
case 'm':
case 'M':
mult = MEGABYTE;
break;
case 'g':
case 'G':
mult = GIGABYTE;
break;
default:
(void) fprintf(stderr,
gettext("unknown size %s\n"), argv[1]);
usage();
}
for (i = 0; i <= (len-2); i++) {
if (!isdigit(argv[1][i])) {
(void) fprintf(stderr,
gettext("unknown size %s\n"), argv[1]);
usage();
}
}
argv[1][len-1] = '\0';
}
size = ((off_t)atoll(argv[1]) * (off_t)mult);
argv++;
argc--;
while (argc > 1) {
int fd;
if (verbose)
(void) fprintf(stdout, gettext("%s %lld bytes\n"),
argv[1], (offset_t)size);
fd = open(argv[1], O_CREAT|O_TRUNC|O_RDWR, FILE_MODE);
if (fd < 0) {
saverr = errno;
(void) fprintf(stderr,
gettext("Could not open %s: %s\n"),
argv[1], strerror(saverr));
errors++;
argv++;
argc--;
continue;
}
if (lseek(fd, (off_t)size-1, SEEK_SET) < 0) {
saverr = errno;
(void) fprintf(stderr, gettext(
"Could not seek to offset %ld in %s: %s\n"),
(unsigned long)size-1, argv[1], strerror(saverr));
(void) close(fd);
errors++;
argv++;
argc--;
continue;
} else if (write(fd, "", 1) != 1) {
saverr = errno;
(void) fprintf(stderr, gettext(
"Could not set length of %s: %s\n"),
argv[1], strerror(saverr));
(void) close(fd);
errors++;
argv++;
argc--;
continue;
}
if (!nobytes) {
off_t written = 0;
struct stat64 st;
if (lseek(fd, (off_t)0, SEEK_SET) < 0) {
saverr = errno;
(void) fprintf(stderr, gettext(
"Could not seek to beginning of %s: %s\n"),
argv[1], strerror(saverr));
(void) close(fd);
errors++;
argv++;
argc--;
continue;
}
if (fstat64(fd, &st) < 0) {
saverr = errno;
(void) fprintf(stderr, gettext(
"Could not fstat64 %s: %s\n"),
argv[1], strerror(saverr));
(void) close(fd);
errors++;
argv++;
argc--;
continue;
}
if (bufsz != st.st_blksize) {
if (buf)
free(buf);
bufsz = (size_t)st.st_blksize;
buf = calloc(bufsz, 1);
if (buf == NULL) {
(void) fprintf(stderr, gettext(
"Could not allocate buffer of"
" size %d\n"), (int)bufsz);
(void) close(fd);
bufsz = 0;
errors++;
argv++;
argc--;
continue;
}
}
while (written < size) {
ssize_t result;
size_t bytes = (size_t)MIN(bufsz, size-written);
if ((result = write(fd, buf, bytes)) !=
(ssize_t)bytes) {
saverr = errno;
if (result < 0)
result = 0;
written += result;
(void) fprintf(stderr, gettext(
"%s: initialized %lu of %lu bytes: %s\n"),
argv[1], (unsigned long)written,
(unsigned long)size,
strerror(saverr));
errors++;
break;
}
written += bytes;
}
/*
* A write(2) call in the above loop failed so
* close out this file and go on (error was
* already incremented when the write(2) failed).
*/
if (written < size) {
(void) close(fd);
argv++;
argc--;
continue;
}
}
if (close(fd) < 0) {
saverr = errno;
(void) fprintf(stderr, gettext(
"Error encountered when closing %s: %s\n"),
argv[1], strerror(saverr));
errors++;
argv++;
argc--;
continue;
}
/*
* Only set the modes (including the sticky bit) if we
* had no problems. It is not an error for the chmod(2)
* to fail, but do issue a warning.
*/
if (chmod(argv[1], FILE_MODE) < 0)
(void) fprintf(stderr, gettext(
"warning: couldn't set mode to %#o\n"), FILE_MODE);
argv++;
argc--;
}
return (errors);
}
static void usage()
{
(void) fprintf(stderr, gettext(
"Usage: mkfile [-nv] <size>[g|k|b|m] <name1> [<name2>] ...\n"));
exit(1);
/* NOTREACHED */
}
+1
View File
@@ -0,0 +1 @@
/mkfiles
+6
View File
@@ -0,0 +1,6 @@
include $(top_srcdir)/config/Rules.am
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
pkgexec_PROGRAMS = mkfiles
mkfiles_SOURCES = mkfiles.c
+65
View File
@@ -0,0 +1,65 @@
/*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*/
/*
* Copyright (c) 2016 by Delphix. All rights reserved.
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/param.h>
#define MAX_INT_LENGTH 10
static void
usage(char *msg, int exit_value)
{
(void) fprintf(stderr, "mkfiles basename max_file [min_file]\n");
(void) fprintf(stderr, "%s\n", msg);
exit(exit_value);
}
int
main(int argc, char **argv)
{
unsigned int numfiles = 0;
unsigned int first_file = 0;
unsigned int i;
char buf[MAXPATHLEN];
if (argc < 3 || argc > 4)
usage("Invalid number of arguments", -1);
if (sscanf(argv[2], "%u", &numfiles) != 1)
usage("Invalid maximum file", -2);
if (argc == 4 && sscanf(argv[3], "%u", &first_file) != 1)
usage("Invalid first file", -3);
if (numfiles < first_file)
usage("First file larger than last file", -3);
for (i = first_file; i <= numfiles; i++) {
int fd;
(void) snprintf(buf, MAXPATHLEN, "%s%u", argv[1], i);
if ((fd = open(buf, O_CREAT | O_EXCL, O_RDWR)) == -1) {
(void) fprintf(stderr, "Failed to create %s %s\n", buf,
strerror(errno));
return (-4);
}
(void) close(fd);
}
return (0);
}
+1
View File
@@ -0,0 +1 @@
/mktree
+6
View File
@@ -0,0 +1,6 @@
include $(top_srcdir)/config/Rules.am
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
pkgexec_PROGRAMS = mktree
mktree_SOURCES = mktree.c
+183
View File
@@ -0,0 +1,183 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <attr/xattr.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <sys/param.h>
#define TYPE_D 'D'
#define TYPE_F 'F'
static char fdname[MAXPATHLEN] = {0};
static char *pbasedir = NULL;
static int nlevel = 2;
static int ndir = 2;
static int nfile = 2;
static void usage(char *this);
static void crtfile(char *pname);
static char *getfdname(char *pdir, char type, int level, int dir, int file);
static int mktree(char *pbasedir, int level);
int
main(int argc, char *argv[])
{
int c, ret;
while ((c = getopt(argc, argv, "b:l:d:f:")) != -1) {
switch (c) {
case 'b':
pbasedir = optarg;
break;
case 'l':
nlevel = atoi(optarg);
break;
case 'd':
ndir = atoi(optarg);
break;
case 'f':
nfile = atoi(optarg);
break;
case '?':
usage(argv[0]);
}
}
if (nlevel < 0 || ndir < 0 || nfile < 0 || pbasedir == NULL) {
usage(argv[0]);
}
ret = mktree(pbasedir, 1);
return (ret);
}
static void
usage(char *this)
{
(void) fprintf(stderr,
"\tUsage: %s -b <base_dir> -l [nlevel] -d [ndir] -f [nfile]\n",
this);
exit(1);
}
static int
mktree(char *pdir, int level)
{
int d, f;
char dname[MAXPATHLEN] = {0};
char fname[MAXPATHLEN] = {0};
if (level > nlevel) {
return (1);
}
for (d = 0; d < ndir; d++) {
(void) memset(dname, '\0', sizeof (dname));
(void) strcpy(dname, getfdname(pdir, TYPE_D, level, d, 0));
if (mkdir(dname, 0777) != 0) {
(void) fprintf(stderr, "mkdir(%s) failed."
"\n[%d]: %s.\n",
dname, errno, strerror(errno));
exit(errno);
}
/*
* No sub-directory need be created, only create files in it.
*/
if (mktree(dname, level+1) != 0) {
for (f = 0; f < nfile; f++) {
(void) memset(fname, '\0', sizeof (fname));
(void) strcpy(fname,
getfdname(dname, TYPE_F, level+1, d, f));
crtfile(fname);
}
}
}
for (f = 0; f < nfile; f++) {
(void) memset(fname, '\0', sizeof (fname));
(void) strcpy(fname, getfdname(pdir, TYPE_F, level, d, f));
crtfile(fname);
}
return (0);
}
static char *
getfdname(char *pdir, char type, int level, int dir, int file)
{
(void) snprintf(fdname, sizeof (fdname),
"%s/%c-l%dd%df%d", pdir, type, level, dir, file);
return (fdname);
}
static void
crtfile(char *pname)
{
int fd = -1;
int i, size;
char *context = "0123456789ABCDF";
char *pbuf;
if (pname == NULL) {
exit(1);
}
size = sizeof (char) * 1024;
pbuf = (char *)valloc(size);
for (i = 0; i < size / strlen(context); i++) {
int offset = i * strlen(context);
(void) snprintf(pbuf+offset, size-offset, "%s", context);
}
if ((fd = open(pname, O_CREAT|O_RDWR, 0777)) < 0) {
(void) fprintf(stderr, "open(%s, O_CREAT|O_RDWR, 0777) failed."
"\n[%d]: %s.\n", pname, errno, strerror(errno));
exit(errno);
}
if (write(fd, pbuf, 1024) < 1024) {
(void) fprintf(stderr, "write(fd, pbuf, 1024) failed."
"\n[%d]: %s.\n", errno, strerror(errno));
exit(errno);
}
if (fsetxattr(fd, "xattr", pbuf, 1024, 0) < 0) {
(void) fprintf(stderr, "fsetxattr(fd, \"xattr\", pbuf, "
"1024, 0) failed.\n[%d]: %s.\n", errno, strerror(errno));
exit(errno);
}
(void) close(fd);
free(pbuf);
}
+1
View File
@@ -0,0 +1 @@
/mmap_exec
@@ -0,0 +1,6 @@
include $(top_srcdir)/config/Rules.am
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
pkgexec_PROGRAMS = mmap_exec
mmap_exec_SOURCES = mmap_exec.c
+69
View File
@@ -0,0 +1,69 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2013 by Delphix. All rights reserved.
*/
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <errno.h>
int
main(int argc, char *argv[])
{
int fd;
struct stat statbuf;
if (argc != 2) {
(void) printf("Error: missing binary name.\n");
(void) printf("Usage:\n\t%s <binary name>\n",
argv[0]);
return (1);
}
errno = 0;
if ((fd = open(argv[1], O_RDONLY)) < 0) {
perror("open");
return (errno);
}
if (fstat(fd, &statbuf) < 0) {
perror("fstat");
return (errno);
}
if (mmap(0, statbuf.st_size,
PROT_EXEC, MAP_SHARED, fd, 0) == MAP_FAILED) {
perror("mmap");
return (errno);
}
return (0);
}
+1
View File
@@ -0,0 +1 @@
/mmapwrite
@@ -0,0 +1,7 @@
include $(top_srcdir)/config/Rules.am
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
pkgexec_PROGRAMS = mmapwrite
mmapwrite_SOURCES = mmapwrite.c
mmapwrite_LDADD = -lpthread
+97
View File
@@ -0,0 +1,97 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <pthread.h>
/*
* --------------------------------------------------------------------
* Bug Id: 5032643
*
* Simply writing to a file and mmaping that file at the same time can
* result in deadlock. Nothing perverse like writing from the file's
* own mapping is required.
* --------------------------------------------------------------------
*/
static void *
mapper(void *fdp)
{
void *addr;
int fd = *(int *)fdp;
if ((addr =
mmap(0, 8192, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
perror("mmap");
exit(1);
}
for (;;) {
if (mmap(addr, 8192, PROT_READ,
MAP_SHARED|MAP_FIXED, fd, 0) == MAP_FAILED) {
perror("mmap");
exit(1);
}
}
/* NOTREACHED */
return ((void *)1);
}
int
main(int argc, char **argv)
{
int fd;
char buf[BUFSIZ];
pthread_t tid;
if (argc != 2) {
(void) printf("usage: %s <file name>\n", argv[0]);
exit(1);
}
if ((fd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666)) == -1) {
perror("open");
exit(1);
}
(void) pthread_setconcurrency(2);
if (pthread_create(&tid, NULL, mapper, &fd) != 0) {
perror("pthread_create");
exit(1);
}
for (;;) {
if (write(fd, buf, sizeof (buf)) == -1) {
perror("write");
exit(1);
}
}
/* NOTREACHED */
return (0);
}
@@ -0,0 +1 @@
/randfree_file
@@ -0,0 +1,6 @@
include $(top_srcdir)/config/Rules.am
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
pkgexec_PROGRAMS = randfree_file
randfree_file_SOURCES = randfree_file.c
@@ -0,0 +1,105 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include "../file_common.h"
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/falloc.h>
/*
* Create a file with assigned size and then free the specified
* section of the file
*/
static void usage(char *progname);
static void
usage(char *progname)
{
(void) fprintf(stderr,
"usage: %s [-l filesize] [-s start-offset]"
"[-n section-len] filename\n", progname);
exit(1);
}
int
main(int argc, char *argv[])
{
char *filename = NULL;
char *buf;
size_t filesize = 0;
off_t start_off = 0;
off_t off_len = 0;
int fd, ch;
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
while ((ch = getopt(argc, argv, "l:s:n:")) != EOF) {
switch (ch) {
case 'l':
filesize = atoll(optarg);
break;
case 's':
start_off = atoll(optarg);
break;
case 'n':
off_len = atoll(optarg);
break;
default:
usage(argv[0]);
break;
}
}
if (optind == argc - 1)
filename = argv[optind];
else
usage(argv[0]);
buf = (char *)malloc(filesize);
if ((fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, mode)) < 0) {
perror("open");
return (1);
}
if (write(fd, buf, filesize) < filesize) {
perror("write");
return (1);
}
if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
start_off, off_len) < 0) {
perror("fallocate");
return (1);
}
free(buf);
return (0);
}
+1
View File
@@ -0,0 +1 @@
/readmmap
+6
View File
@@ -0,0 +1,6 @@
include $(top_srcdir)/config/Rules.am
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
pkgexec_PROGRAMS = readmmap
readmmap_SOURCES = readmmap.c
+138
View File
@@ -0,0 +1,138 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* --------------------------------------------------------------
* BugId 5047993 : Getting bad read data.
*
* Usage: readmmap <filename>
*
* where:
* filename is an absolute path to the file name.
*
* Return values:
* 1 : error
* 0 : no errors
* --------------------------------------------------------------
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/mman.h>
#include <time.h>
int
main(int argc, char **argv)
{
char *filename = "badfile";
size_t size = 4395;
size_t idx = 0;
char *buf = NULL;
char *map = NULL;
int fd = -1, bytes, retval = 0;
unsigned seed;
if (argc < 2 || optind == argc) {
(void) fprintf(stderr,
"usage: %s <file name>\n", argv[0]);
exit(1);
}
if ((buf = calloc(1, size)) == NULL) {
perror("calloc");
exit(1);
}
filename = argv[optind];
(void) remove(filename);
fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666);
if (fd == -1) {
perror("open to create");
retval = 1;
goto end;
}
bytes = write(fd, buf, size);
if (bytes != size) {
(void) printf("short write: %d != %zd\n", bytes, size);
retval = 1;
goto end;
}
map = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (map == MAP_FAILED) {
perror("mmap");
retval = 1;
goto end;
}
seed = time(NULL);
srandom(seed);
idx = random() % size;
map[idx] = 1;
if (msync(map, size, MS_SYNC) != 0) {
perror("msync");
retval = 1;
goto end;
}
if (munmap(map, size) != 0) {
perror("munmap");
retval = 1;
goto end;
}
bytes = pread(fd, buf, size, 0);
if (bytes != size) {
(void) printf("short read: %d != %zd\n", bytes, size);
retval = 1;
goto end;
}
if (buf[idx] != 1) {
(void) printf(
"bad data from read! got buf[%zd]=%d, expected 1\n",
idx, buf[idx]);
retval = 1;
goto end;
}
(void) printf("good data from read: buf[%zd]=1\n", idx);
end:
if (fd != -1) {
(void) close(fd);
}
if (buf != NULL) {
free(buf);
}
return (retval);
}
@@ -0,0 +1 @@
/rename_dir
@@ -0,0 +1,6 @@
include $(top_srcdir)/config/Rules.am
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
pkgexec_PROGRAMS = rename_dir
rename_dir_SOURCES = rename_dir.c
@@ -0,0 +1,88 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2012 by Delphix. All rights reserved.
*/
/*
* Assertion:
* Create two directory trees in zfs filesystem, and rename
* directory across the directory structure. ZFS can handle
* the race situation.
*/
/*
* Need to create the following directory structures before
* running this program:
*
* mkdir -p 1/2/3/4/5 a/b/c/d/e
*/
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <strings.h>
int
main(int argc, char *argvp[])
{
int i = 1;
switch (fork()) {
case -1:
perror("fork");
exit(1);
break;
case 0:
while (i > 0) {
int c_count = 0;
if (rename("a/b/c", "1/2/3/c") == 0)
c_count++;
if (rename("1/2/3/c", "a/b/c") == 0)
c_count++;
if (c_count) {
(void) fprintf(stderr, "c_count: %d", c_count);
}
}
break;
default:
while (i > 0) {
int p_count = 0;
if (rename("1", "a/b/c/d/e/1") == 0)
p_count++;
if (rename("a/b/c/d/e/1", "1") == 0)
p_count++;
if (p_count) {
(void) fprintf(stderr, "p_count: %d", p_count);
}
}
break;
}
return (0);
}
@@ -0,0 +1 @@
/rm_lnkcnt_zero_file
@@ -0,0 +1,7 @@
include $(top_srcdir)/config/Rules.am
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
pkgexec_PROGRAMS = rm_lnkcnt_zero_file
rm_lnkcnt_zero_file_SOURCES = rm_lnkcnt_zero_file.c
rm_lnkcnt_zero_file_LDADD = -lpthread
@@ -0,0 +1,155 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2012 by Delphix. All rights reserved.
*/
/*
* --------------------------------------------------------------------
* The purpose of this test is to see if the bug reported (#4723351) for
* UFS exists when using a ZFS file system.
* --------------------------------------------------------------------
*
*/
#define _REENTRANT 1
#include <stdio.h>
#include <fcntl.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
static const int TRUE = 1;
static char *filebase;
static int
pickidx(void)
{
return (random() % 1000);
}
/* ARGSUSED */
static void *
mover(void *a)
{
char buf[256];
int idx, len, ret;
len = strlen(filebase) + 5;
while (TRUE) {
idx = pickidx();
(void) snprintf(buf, len, "%s.%03d", filebase, idx);
ret = rename(filebase, buf);
if (ret < 0 && errno != ENOENT)
(void) perror("renaming file");
}
return (NULL);
}
/* ARGSUSED */
static void *
cleaner(void *a)
{
char buf[256];
int idx, len, ret;
len = strlen(filebase) + 5;
while (TRUE) {
idx = pickidx();
(void) snprintf(buf, len, "%s.%03d", filebase, idx);
ret = remove(buf);
if (ret < 0 && errno != ENOENT)
(void) perror("removing file");
}
return (NULL);
}
static void *
writer(void *a)
{
int *fd = (int *)a;
int ret;
while (TRUE) {
(void) close (*fd);
*fd = open(filebase, O_APPEND | O_RDWR | O_CREAT, 0644);
if (*fd < 0)
perror("refreshing file");
ret = write(*fd, "test\n", 5);
if (ret != 5)
perror("writing file");
}
return (NULL);
}
int
main(int argc, char **argv)
{
int fd;
pthread_t tid;
if (argc == 1) {
(void) printf("Usage: %s <filebase>\n", argv[0]);
exit(-1);
}
filebase = argv[1];
fd = open(filebase, O_APPEND | O_RDWR | O_CREAT, 0644);
if (fd < 0) {
perror("creating test file");
exit(-1);
}
(void) pthread_setconcurrency(4); /* 3 threads + main */
(void) pthread_create(&tid, NULL, mover, NULL);
(void) pthread_create(&tid, NULL, cleaner, NULL);
(void) pthread_create(&tid, NULL, writer, (void *) &fd);
while (TRUE) {
int ret;
struct stat st;
ret = stat(filebase, &st);
if (ret == 0 && (st.st_nlink > 2 || st.st_nlink < 1)) {
(void) printf("st.st_nlink = %d, exiting\n", \
(int)st.st_nlink);
exit(0);
}
(void) sleep(1);
}
return (0);
}
@@ -0,0 +1 @@
/threadsappend
@@ -0,0 +1,7 @@
include $(top_srcdir)/config/Rules.am
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
pkgexec_PROGRAMS = threadsappend
threadsappend_SOURCES = threadsappend.c
threadsappend_LDADD = -lpthread
@@ -0,0 +1,135 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2013 by Delphix. All rights reserved.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
/*
* The size of the output file, "go.out", should be 80*8192*2 = 1310720
*
* $ cd /tmp; go; ls -l go.out
* done.
* -rwxr-xr-x 1 jdm staff 1310720 Apr 13 19:45 go.out
* $ cd /zfs; go; ls -l go.out
* done.
* -rwxr-xr-x 1 jdm staff 663552 Apr 13 19:45 go.out
*
* The file on zfs is short as it does not appear that zfs is making the
* implicit seek to EOF and the actual write atomic. From the SUSv3
* interface spec, behavior is undefined if concurrent writes are performed
* from multi-processes to a single file. So I don't know if this is a
* standards violation, but I cannot find any such disclaimers in our
* man pages. This issue came up at a customer site in another context, and
* the suggestion was to open the file with O_APPEND, but that wouldn't
* help with zfs(see 4977529). Also see bug# 5031301.
*/
static int outfd = 0;
static void *
go(void *data)
{
int ret, i = 0, n = *(int *)data;
char buf[8192] = {0};
(void) memset(buf, n, sizeof (buf));
for (i = 0; i < 80; i++) {
ret = write(outfd, buf, sizeof (buf));
if (ret != sizeof (buf))
perror("write");
}
return (NULL);
}
static void
usage(void)
{
(void) fprintf(stderr,
"usage: zfs_threadsappend <file name>\n");
exit(1);
}
int
main(int argc, char **argv)
{
pthread_t tid;
int ret = 0;
long ncpus = 0;
int i;
if (argc != 2) {
usage();
}
ncpus = sysconf(_SC_NPROCESSORS_ONLN);
if (ncpus < 0) {
(void) fprintf(stderr,
"Invalid return from sysconf(_SC_NPROCESSORS_ONLN)"
" : errno (decimal)=%d\n", errno);
exit(1);
}
if (ncpus < 2) {
(void) fprintf(stderr,
"Must execute this binary on a multi-processor system\n");
exit(1);
}
outfd = open(argv[optind++], O_RDWR|O_CREAT|O_APPEND|O_TRUNC, 0777);
if (outfd == -1) {
(void) fprintf(stderr,
"zfs_threadsappend: "
"open(%s, O_RDWR|O_CREAT|O_APPEND|O_TRUNC, 0777)"
" failed\n", argv[optind]);
perror("open");
exit(1);
}
for (i = 0; i < 2; i++) {
ret = pthread_create(&tid, NULL, go, (void *)&i);
if (ret != 0) {
(void) fprintf(stderr,
"zfs_threadsappend: thr_create(#%d) "
"failed error=%d\n", i+1, ret);
exit(1);
}
}
while (pthread_join(tid, NULL) == 0)
continue;
return (0);
}
+1
View File
@@ -0,0 +1 @@
/xattrtest
@@ -0,0 +1,6 @@
include $(top_srcdir)/config/Rules.am
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
pkgexec_PROGRAMS = xattrtest
xattrtest_SOURCES = xattrtest.c
+641
View File
@@ -0,0 +1,641 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2016 Lawrence Livermore National Security, LLC.
*/
/*
* An extended attribute (xattr) correctness test. This program creates
* N files and sets M attrs on them of size S. Optionally is will verify
* a pattern stored in the xattr.
*/
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include <attr/xattr.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <linux/limits.h>
extern char *program_invocation_short_name;
#define ERROR(fmt, ...) \
fprintf(stderr, "%s: %s:%d: %s: " fmt "\n", \
program_invocation_short_name, __FILE__, __LINE__, \
__func__, ## __VA_ARGS__);
static const char shortopts[] = "hvycdn:f:x:s:p:t:e:rRk";
static const struct option longopts[] = {
{ "help", no_argument, 0, 'h' },
{ "verbose", no_argument, 0, 'v' },
{ "verify", no_argument, 0, 'y' },
{ "nth", required_argument, 0, 'n' },
{ "files", required_argument, 0, 'f' },
{ "xattrs", required_argument, 0, 'x' },
{ "size", required_argument, 0, 's' },
{ "path", required_argument, 0, 'p' },
{ "synccaches", no_argument, 0, 'c' },
{ "dropcaches", no_argument, 0, 'd' },
{ "script", required_argument, 0, 't' },
{ "seed", required_argument, 0, 'e' },
{ "random", no_argument, 0, 'r' },
{ "randomvalue", no_argument, 0, 'R' },
{ "keep", no_argument, 0, 'k' },
{ 0, 0, 0, 0 }
};
static int verbose = 0;
static int verify = 0;
static int synccaches = 0;
static int dropcaches = 0;
static int nth = 0;
static int files = 1000;
static int xattrs = 1;
static int size = 1;
static int size_is_random = 0;
static int value_is_random = 0;
static int keep_files = 0;
static char path[PATH_MAX] = "/tmp/xattrtest";
static char script[PATH_MAX] = "/bin/true";
static int
usage(int argc, char **argv) {
fprintf(stderr,
"usage: %s [-hvycdrRk] [-n <nth>] [-f <files>] [-x <xattrs>]\n"
" [-s <bytes>] [-p <path>] [-t <script> ]\n", argv[0]);
fprintf(stderr,
" --help -h This help\n"
" --verbose -v Increase verbosity\n"
" --verify -y Verify xattr contents\n"
" --nth -n <nth> Print every nth file\n"
" --files -f <files> Set xattrs on N files\n"
" --xattrs -x <xattrs> Set N xattrs on each file\n"
" --size -s <bytes> Set N bytes per xattr\n"
" --path -p <path> Path to files\n"
" --synccaches -c Sync caches between phases\n"
" --dropcaches -d Drop caches between phases\n"
" --script -t <script> Exec script between phases\n"
" --seed -e <seed> Random seed value\n"
" --random -r Randomly sized xattrs [16-size]\n"
" --randomvalue -R Random xattr values\n"
" --keep -k Don't unlink files\n\n");
return (0);
}
static int
parse_args(int argc, char **argv)
{
long seed = time(NULL);
int c;
int rc;
while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
switch (c) {
case 'h':
return (usage(argc, argv));
case 'v':
verbose++;
break;
case 'y':
verify = 1;
if (value_is_random != 0) {
fprintf(stderr,
"Error: -y and -R are incompatible.\n");
rc = 1;
}
break;
case 'n':
nth = strtol(optarg, NULL, 0);
break;
case 'f':
files = strtol(optarg, NULL, 0);
break;
case 'x':
xattrs = strtol(optarg, NULL, 0);
break;
case 's':
size = strtol(optarg, NULL, 0);
if (size > XATTR_SIZE_MAX) {
fprintf(stderr, "Error: the size may not be "
"greater than %d\n", XATTR_SIZE_MAX);
rc = 1;
}
break;
case 'p':
strncpy(path, optarg, PATH_MAX);
break;
case 'c':
synccaches = 1;
break;
case 'd':
dropcaches = 1;
break;
case 't':
strncpy(script, optarg, PATH_MAX);
break;
case 'e':
seed = strtol(optarg, NULL, 0);
break;
case 'r':
size_is_random = 1;
break;
case 'R':
value_is_random = 1;
if (verify != 0) {
fprintf(stderr,
"Error: -y and -R are incompatible.\n");
rc = 1;
}
break;
case 'k':
keep_files = 1;
break;
default:
rc = 1;
break;
}
}
if (rc != 0)
return (rc);
srandom(seed);
if (verbose) {
fprintf(stdout, "verbose: %d\n", verbose);
fprintf(stdout, "verify: %d\n", verify);
fprintf(stdout, "nth: %d\n", nth);
fprintf(stdout, "files: %d\n", files);
fprintf(stdout, "xattrs: %d\n", xattrs);
fprintf(stdout, "size: %d\n", size);
fprintf(stdout, "path: %s\n", path);
fprintf(stdout, "synccaches: %d\n", synccaches);
fprintf(stdout, "dropcaches: %d\n", dropcaches);
fprintf(stdout, "script: %s\n", script);
fprintf(stdout, "seed: %ld\n", seed);
fprintf(stdout, "random size: %d\n", size_is_random);
fprintf(stdout, "random value: %d\n", value_is_random);
fprintf(stdout, "keep: %d\n", keep_files);
fprintf(stdout, "%s", "\n");
}
return (rc);
}
static int
drop_caches(void)
{
char file[] = "/proc/sys/vm/drop_caches";
int fd, rc;
fd = open(file, O_WRONLY);
if (fd == -1) {
ERROR("Error %d: open(\"%s\", O_WRONLY)\n", errno, file);
return (errno);
}
rc = write(fd, "3", 1);
if ((rc == -1) || (rc != 1)) {
ERROR("Error %d: write(%d, \"3\", 1)\n", errno, fd);
return (errno);
}
rc = close(fd);
if (rc == -1) {
ERROR("Error %d: close(%d)\n", errno, fd);
return (errno);
}
return (0);
}
static int
run_process(const char *path, char *argv[])
{
pid_t pid;
int rc, devnull_fd;
pid = vfork();
if (pid == 0) {
devnull_fd = open("/dev/null", O_WRONLY);
if (devnull_fd < 0)
_exit(-1);
(void) dup2(devnull_fd, STDOUT_FILENO);
(void) dup2(devnull_fd, STDERR_FILENO);
close(devnull_fd);
(void) execvp(path, argv);
_exit(-1);
} else if (pid > 0) {
int status;
while ((rc = waitpid(pid, &status, 0)) == -1 && errno == EINTR);
if (rc < 0 || !WIFEXITED(status))
return (-1);
return (WEXITSTATUS(status));
}
return (-1);
}
static int
post_hook(char *phase)
{
char *argv[3] = { script, phase, (char *)0 };
int rc;
if (synccaches)
sync();
if (dropcaches) {
rc = drop_caches();
if (rc)
return (rc);
}
rc = run_process(script, argv);
if (rc)
return (rc);
return (0);
}
#define USEC_PER_SEC 1000000
static void
timeval_normalize(struct timeval *tv, time_t sec, suseconds_t usec)
{
while (usec >= USEC_PER_SEC) {
usec -= USEC_PER_SEC;
sec++;
}
while (usec < 0) {
usec += USEC_PER_SEC;
sec--;
}
tv->tv_sec = sec;
tv->tv_usec = usec;
}
static void
timeval_sub(struct timeval *delta, struct timeval *tv1, struct timeval *tv2)
{
timeval_normalize(delta,
tv1->tv_sec - tv2->tv_sec,
tv1->tv_usec - tv2->tv_usec);
}
static int
create_files(void)
{
int i, rc;
char *file = NULL;
struct timeval start, stop, delta;
file = malloc(PATH_MAX);
if (file == NULL) {
rc = ENOMEM;
ERROR("Error %d: malloc(%d) bytes for file name\n",
rc, PATH_MAX);
goto out;
}
(void) gettimeofday(&start, NULL);
for (i = 1; i <= files; i++) {
(void) sprintf(file, "%s/file-%d", path, i);
if (nth && ((i % nth) == 0))
fprintf(stdout, "create: %s\n", file);
rc = unlink(file);
if ((rc == -1) && (errno != ENOENT)) {
ERROR("Error %d: unlink(%s)\n", errno, file);
rc = errno;
goto out;
}
rc = open(file, O_CREAT, 0644);
if (rc == -1) {
ERROR("Error %d: open(%s, O_CREATE, 0644)\n",
errno, file);
rc = errno;
goto out;
}
rc = close(rc);
if (rc == -1) {
ERROR("Error %d: close(%d)\n", errno, rc);
rc = errno;
goto out;
}
}
(void) gettimeofday(&stop, NULL);
timeval_sub(&delta, &stop, &start);
fprintf(stdout, "create: %d.%d seconds\n",
(int)delta.tv_sec, (int)delta.tv_usec);
rc = post_hook("post");
out:
if (file)
free(file);
return (rc);
}
static int
get_random_bytes(char *buf, size_t bytes)
{
int rand;
ssize_t bytes_read = 0;
rand = open("/dev/urandom", O_RDONLY);
if (rand < 0)
return (rand);
while (bytes_read < bytes) {
ssize_t rc = read(rand, buf + bytes_read, bytes - bytes_read);
if (rc < 0)
break;
bytes_read += rc;
}
(void) close(rand);
return (bytes_read);
}
static int
setxattrs(void)
{
int i, j, rnd_size = size, shift, rc = 0;
char name[XATTR_NAME_MAX];
char *value = NULL;
char *file = NULL;
struct timeval start, stop, delta;
value = malloc(XATTR_SIZE_MAX);
if (value == NULL) {
rc = ENOMEM;
ERROR("Error %d: malloc(%d) bytes for xattr value\n",
rc, XATTR_SIZE_MAX);
goto out;
}
file = malloc(PATH_MAX);
if (file == NULL) {
rc = ENOMEM;
ERROR("Error %d: malloc(%d) bytes for file name\n",
rc, PATH_MAX);
goto out;
}
(void) gettimeofday(&start, NULL);
for (i = 1; i <= files; i++) {
(void) sprintf(file, "%s/file-%d", path, i);
if (nth && ((i % nth) == 0))
fprintf(stdout, "setxattr: %s\n", file);
for (j = 1; j <= xattrs; j++) {
if (size_is_random)
rnd_size = (random() % (size - 16)) + 16;
(void) sprintf(name, "user.%d", j);
if (value_is_random) {
rc = get_random_bytes(value, rnd_size);
if (rc < rnd_size) {
ERROR("Error %d: get_random_bytes() "
"wanted %d got %d\n", errno,
rnd_size, rc);
goto out;
}
} else {
shift = sprintf(value, "size=%d ", rnd_size);
memset(value + shift, 'x', XATTR_SIZE_MAX -
shift);
}
rc = lsetxattr(file, name, value, rnd_size, 0);
if (rc == -1) {
ERROR("Error %d: lsetxattr(%s, %s, ..., %d)\n",
errno, file, name, rnd_size);
goto out;
}
}
}
(void) gettimeofday(&stop, NULL);
timeval_sub(&delta, &stop, &start);
fprintf(stdout, "setxattr: %d.%d seconds\n",
(int)delta.tv_sec, (int)delta.tv_usec);
rc = post_hook("post");
out:
if (file)
free(file);
if (value)
free(value);
return (rc);
}
static int
getxattrs(void)
{
int i, j, rnd_size, shift, rc = 0;
char name[XATTR_NAME_MAX];
char *verify_value = NULL;
char *value = NULL;
char *file = NULL;
struct timeval start, stop, delta;
verify_value = malloc(XATTR_SIZE_MAX);
if (verify_value == NULL) {
rc = ENOMEM;
ERROR("Error %d: malloc(%d) bytes for xattr verify\n",
rc, XATTR_SIZE_MAX);
goto out;
}
value = malloc(XATTR_SIZE_MAX);
if (value == NULL) {
rc = ENOMEM;
ERROR("Error %d: malloc(%d) bytes for xattr value\n",
rc, XATTR_SIZE_MAX);
goto out;
}
file = malloc(PATH_MAX);
if (file == NULL) {
rc = ENOMEM;
ERROR("Error %d: malloc(%d) bytes for file name\n",
rc, PATH_MAX);
goto out;
}
(void) gettimeofday(&start, NULL);
for (i = 1; i <= files; i++) {
(void) sprintf(file, "%s/file-%d", path, i);
if (nth && ((i % nth) == 0))
fprintf(stdout, "getxattr: %s\n", file);
for (j = 1; j <= xattrs; j++) {
(void) sprintf(name, "user.%d", j);
rc = lgetxattr(file, name, value, XATTR_SIZE_MAX);
if (rc == -1) {
ERROR("Error %d: lgetxattr(%s, %s, ..., %d)\n",
errno, file, name, XATTR_SIZE_MAX);
goto out;
}
if (verify) {
sscanf(value, "size=%d [a-z]", &rnd_size);
shift = sprintf(verify_value, "size=%d ",
rnd_size);
memset(verify_value + shift, 'x',
XATTR_SIZE_MAX - shift);
if (rnd_size != rc ||
memcmp(verify_value, value, rnd_size)) {
ERROR("Error %d: verify failed\n "
"verify: %s\nvalue: %s\n",
EINVAL, verify_value, value);
goto out;
}
}
}
}
(void) gettimeofday(&stop, NULL);
timeval_sub(&delta, &stop, &start);
fprintf(stdout, "getxattr: %d.%d seconds\n",
(int)delta.tv_sec, (int)delta.tv_usec);
rc = post_hook("post");
out:
if (file)
free(file);
if (value)
free(value);
if (verify_value)
free(verify_value);
return (rc);
}
static int
unlink_files(void)
{
int i, rc;
char *file = NULL;
struct timeval start, stop, delta;
file = malloc(PATH_MAX);
if (file == NULL) {
rc = ENOMEM;
ERROR("Error %d: malloc(%d) bytes for file name\n",
rc, PATH_MAX);
goto out;
}
(void) gettimeofday(&start, NULL);
for (i = 1; i <= files; i++) {
(void) sprintf(file, "%s/file-%d", path, i);
if (nth && ((i % nth) == 0))
fprintf(stdout, "unlink: %s\n", file);
rc = unlink(file);
if ((rc == -1) && (errno != ENOENT)) {
ERROR("Error %d: unlink(%s)\n", errno, file);
return (errno);
}
}
(void) gettimeofday(&stop, NULL);
timeval_sub(&delta, &stop, &start);
fprintf(stdout, "unlink: %d.%d seconds\n",
(int)delta.tv_sec, (int)delta.tv_usec);
rc = post_hook("post");
out:
if (file)
free(file);
return (rc);
}
int
main(int argc, char **argv)
{
int rc;
rc = parse_args(argc, argv);
if (rc)
return (rc);
rc = create_files();
if (rc)
return (rc);
rc = setxattrs();
if (rc)
return (rc);
rc = getxattrs();
if (rc)
return (rc);
if (!keep_files) {
rc = unlink_files();
if (rc)
return (rc);
}
return (0);
}
+2
View File
@@ -0,0 +1,2 @@
/commands.cfg
/default.cfg
+10
View File
@@ -0,0 +1,10 @@
pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/include
dist_pkgdata_SCRIPTS = \
commands.cfg \
default.cfg \
libtest.shlib \
math.shlib \
properties.shlib
EXTRA_DIST = \
zfs_commands.cfg
+119
View File
@@ -0,0 +1,119 @@
export AWK="@AWK@"
export BLOCKDEV="@BLOCKDEV@"
export BASENAME="@BASENAME@"
export BC="@BC@"
export BUNZIP2="@BUNZIP2@"
export BZCAT="@BZCAT@"
export CAT="@CAT@"
export CD="@CD@"
export CHACL="@CHACL@"
export CHGRP="@CHGRP@"
export CHMOD="@CHMOD@"
export CHOWN="@CHOWN@"
export CKSUM="@CKSUM@"
export CMP="@CMP@"
export COMPRESS="@COMPRESS@"
export COREADM="@COREADM@"
export CP="@CP@"
export CPIO="@CPIO@"
export CUT="@CUT@"
export DATE="@DATE@"
export DD="@DD@"
export DF="@DF@"
export DIFF="@DIFF@"
export DIRCMP="@DIRCMP@"
export DIRNAME="@DIRNAME@"
export DU="@DU@"
export DUMPADM="@DUMPADM@"
export ECHO="@ECHO@"
export EGREP="@EGREP@"
export FDISK="@FDISK@"
export FGREP="@FGREP@"
export FILE="@FILE@"
export FIND="@FIND@"
export FORMAT="@FORMAT@"
export FSCK="@FSCK@"
export GETENT="@GETENT@"
export GETFACL="@GETFACL@"
export GETMAJOR="@GETMAJOR@"
export GNUDD="@GNUDD@"
export GREP="@GREP@"
export GROUPADD="@GROUPADD@"
export GROUPDEL="@GROUPDEL@"
export GROUPMOD="@GROUPMOD@"
export HEAD="@HEAD@"
export HOSTNAME="@HOSTNAME@"
export ID="@ID@"
export ISAINFO="@ISAINFO@"
export KILL="@KILL@"
export KSH="@KSH@"
export KSTAT="@KSTAT@"
export LOCKFS="@LOCKFS@"
export LOFIADM="@LOFIADM@"
export LOGNAME="@LOGNAME@"
export LS="@LS@"
export MD5SUM="@MD5SUM@"
export MKDIR="@MKDIR@"
export MKNOD="@MKNOD@"
export MKTEMP="@MKTEMP@"
export MNTTAB="@MNTTAB@"
export MODINFO="@MODINFO@"
export MODUNLOAD="@MODUNLOAD@"
export MOUNT="@MOUNT@"
export MV="@MV@"
export NAWK="@AWK@"
export NEWFS="@NEWFS@"
export NPROC="@NPROC@"
export PAGESIZE="@PAGESIZE@"
export PFEXEC="@PFEXEC@"
export PGREP="@PGREP@"
export PING="@PING@"
export PKGINFO="@PKGINFO@"
export PKILL="@PKILL@"
export PRINTF="@PRINTF@"
export PRTVTOC="@PRTVTOC@"
export PS="@PS@"
export PSRINFO="@PSRINFO@"
export PYTHON="@PYTHON@"
export REBOOT="@REBOOT@"
export RM="@RM@"
export RMDIR="@RMDIR@"
export RSH="@RSH@"
export SED="@SED@"
export SETFACL="@SETFACL@"
export SHARE="@SHARE@"
export SHUF="@SHUF@"
export SLEEP="@SLEEP@"
export SORT="@SORT@"
export STRINGS="@STRINGS@"
export SU="@SU@"
export SUM="@SUM@"
export SVCADM="@SVCADM@"
export SVCS="@SVCS@"
export SWAP="@SWAP@"
export SWAPADD="@SWAPADD@"
export SYNC="@SYNC@"
export TAIL="@TAIL@"
export TAR="@TAR@"
export TOUCH="@TOUCH@"
export TR="@TR@"
export TRUE="@TRUE@"
export TRUNCATE="@TRUNCATE@"
export UDEVADM="@UDEVADM@"
export UFSDUMP="@UFSDUMP@"
export UFSRESTORE="@UFSRESTORE@"
export UMASK="@UMASK@"
export UMOUNT="@UMOUNT@"
export UMOUNTALL="@UMOUNTALL@"
export UNAME="@UNAME@"
export UNCOMPRESS="@UNCOMPRESS@"
export UNIQ="@UNIQ@"
export UNSHARE="@UNSHARE@"
export USERADD="@USERADD@"
export USERDEL="@USERDEL@"
export USERMOD="@USERMOD@"
export WAIT="@WAIT@"
export WC="@WC@"
export ZONEADM="@ZONEADM@"
export ZONECFG="@ZONECFG@"
export ZONENAME="@ZONENAME@"
+200
View File
@@ -0,0 +1,200 @@
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#
# Copyright (c) 2016 by Delphix. All rights reserved.
#
. $STF_SUITE/include/commands.cfg
. $STF_SUITE/include/libtest.shlib
# Optionally override the installed ZFS commands to run in-tree
if [[ -f "$STF_SUITE/include/zfs_commands.cfg" ]]; then
. $STF_SUITE/include/zfs_commands.cfg
fi
# Define run length constants
export RT_LONG="3"
export RT_MEDIUM="2"
export RT_SHORT="1"
# Define macro for zone test
export ZONE_POOL="zonepool"
export ZONE_CTR="zonectr"
# Common paths
bindir=@bindir@
sbindir=@sbindir@
helperdir=@datarootdir@/@PACKAGE@/zfs-tests/bin
# ZFS Commands
ZDB=${ZDB:-${sbindir}/zdb}
ZFS=${ZFS:-${sbindir}/zfs}
ZHACK=${ZHACK:-${sbindir}/zhack}
ZINJECT=${ZINJECT:-${sbindir}/zinject}
ZPOOL=${ZPOOL:-${sbindir}/zpool}
ZTEST=${ZTEST:-${sbindir}/ztest}
ZPIOS=${ZPIOS:-${sbindir}/zpios}
# Test Suite Specific Commands
export CHG_USR_EXEC=${CHG_USR_EXEC:-${helperdir}/chg_usr_exec}
export DEVNAME2DEVID=${DEVNAME2DEVID:-${helperdir}/devname2devid}
export DIR_RD_UPDATE=${DIR_RD_UPDATE:-${helperdir}/dir_rd_update}
export FILE_CHECK=${FILE_CHECK:-${helperdir}/file_check}
export FILE_TRUNC=${FILE_TRUNC:-${helperdir}/file_trunc}
export FILE_WRITE=${FILE_WRITE:-${helperdir}/file_write}
export LARGEST_FILE=${LARGEST_FILE:-${helperdir}/largest_file}
export MKBUSY=${MKBUSY:-${helperdir}/mkbusy}
export MKFILE=${MKFILE:-${helperdir}/mkfile}
export MKFILES=${MKFILES:-${helperdir}/mkfiles}
export MKTREE=${MKTREE:-${helperdir}/mktree}
export MMAP_EXEC=${MMAP_EXEC:-${helperdir}/mmap_exec}
export MMAPWRITE=${MMAPWRITE:-${helperdir}/mmapwrite}
export RANDFREE_FILE=${RANDFREE_FILE:-${helperdir}/randfree_file}
export READMMAP=${READMMAP:-${helperdir}/readmmap}
export RENAME_DIR=${RENAME_DIR:-${helperdir}/rename_dir}
export RM_LNKCNT_ZERO_FILE=${RM_LNKCNT_ZERO_FILE:-${helperdir}/rm_lnkcnt_zero_file}
export THREADSAPPEND=${THREADSAPPEND:-${helperdir}/threadsappend}
export XATTRTEST=${XATTRTEST:-${helpdir}/xattrtest}
# ensure we're running in the C locale, since
# localised messages may result in test failures
export LC_ALL="C"
export LANG="C"
#
# pattern to ignore from 'zpool list'.
#
export NO_POOLS="no pools available"
# pattern to ignore from 'zfs list'.
export NO_DATASETS="no datasets available"
export TEST_BASE_DIR="/var/tmp"
# Default to compression ON
export COMPRESSION_PROP=on
# Default to using the checksum
export CHECKSUM_PROP=on
# some common variables used by test scripts :
# some test pool names
export TESTPOOL=testpool.$$
export TESTPOOL1=testpool1.$$
export TESTPOOL2=testpool2.$$
export TESTPOOL3=testpool3.$$
# some test file system names
export TESTFS=testfs.$$
export TESTFS1=testfs1.$$
export TESTFS2=testfs2.$$
export TESTFS3=testfs3.$$
# some test directory names
export TESTDIR=${TEST_BASE_DIR%%/}/testdir$$
export TESTDIR0=${TEST_BASE_DIR%%/}/testdir0$$
export TESTDIR1=${TEST_BASE_DIR%%/}/testdir1$$
export TESTDIR2=${TEST_BASE_DIR%%/}/testdir2$$
export ZFSROOT=
export TESTSNAP=testsnap$$
export TESTSNAP1=testsnap1$$
export TESTSNAP2=testsnap2$$
export TESTCLONE=testclone$$
export TESTCLONE1=testclone1$$
export TESTCLONE2=testclone2$$
export TESTCLCT=testclct$$
export TESTCTR=testctr$$
export TESTCTR1=testctr1$$
export TESTCTR2=testctr2$$
export TESTVOL=testvol$$
export TESTVOL1=testvol1$$
export TESTVOL2=testvol2$$
export TESTFILE0=testfile0.$$
export TESTFILE1=testfile1.$$
export TESTFILE2=testfile2.$$
export LONGPNAME="poolname50charslong_012345678901234567890123456789"
export LONGFSNAME="fsysname50charslong_012345678901234567890123456789"
export SNAPFS="$TESTPOOL/$TESTFS@$TESTSNAP"
export SNAPFS1="$TESTPOOL/$TESTVOL@$TESTSNAP"
export VOLSIZE=150m
export BIGVOLSIZE=1eb
# Default to limit disks to be checked
export MAX_FINDDISKSNUM=6
# For iscsi target support
export ISCSITGTFILE=/tmp/iscsitgt_file
export ISCSITGT_FMRI=svc:/system/iscsitgt:default
#
# finally, if we're running in a local zone
# we take some additional actions
if ! is_global_zone; then
reexport_pool
fi
export ZFS_VERSION=5
export ZFS_ALL_VERSIONS="1 2 3 4 5"
for i in $ZFS_ALL_VERSIONS; do
eval 'export ZFS_VERSION_$i="v${i}-fs"'
done
if is_linux; then
unpack_opts="--sparse -xf"
pack_opts="--sparse -cf"
verbose=" -v"
unpack_preserve=" -xpf"
pack_preserve=" -cpf"
ZVOL_DEVDIR="/dev/zvol"
ZVOL_RDEVDIR="/dev/zvol"
DEV_DSKDIR="/dev"
DEV_RDSKDIR="/dev"
NEWFS_DEFAULT_FS="ext2"
else
unpack_opts="xv"
pack_opts="cf"
verbose="v"
unpack_preserve="xpf"
pack_preserve="cpf"
ZVOL_DEVDIR="/dev/zvol/dsk"
ZVOL_RDEVDIR="/dev/zvol/rdsk"
DEV_DSKDIR="/dev/dsk"
DEV_RDSKDIR="/dev/rdsk"
NEWFS_DEFAULT_FS="ufs"
fi
export unpack_opts pack_opts verbose unpack_preserve pack_preserve \
ZVOL_DEVDIR ZVOL_RDEVDIR NEWFS_DEFAULT_FS DEV_DSKDIR DEV_RDSKDIR
File diff suppressed because it is too large Load Diff
+43
View File
@@ -0,0 +1,43 @@
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2012 by Delphix. All rights reserved.
#
#
# Return 0 if the percentage difference between $a and $b is $percent or
# greater. Return 1 if the percentage is lower or if we would divide by
# zero. For use like this:
#
# Do $action if the calculated percentage is greater or equal to that passed in:
# within_percent A B P && $action
# Do $action if the calculated percentage is less than that passed in:
# within_percent A B P || $action
#
function within_percent
{
typeset a=$1
typeset b=$1
typeset percent=$3
# Set $a or $b to $2 such that a >= b
[[ '1' = $($ECHO "if ($2 > $a) 1" | $BC) ]] && a=$2 || b=$2
# Prevent division by 0
[[ $a =~ [1-9] ]] || return 1
typeset p=$($ECHO "scale=2; $b * 100 / $a" | $BC)
log_note "Comparing $a and $b given $percent% (calculated: $p%)"
[[ '1' = $($ECHO "scale=2; if ($p >= $percent) 1" | $BC) ]] && return 0
return 1
}
+63
View File
@@ -0,0 +1,63 @@
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2012 by Delphix. All rights reserved.
#
typeset -a compress_props=('on' 'off' 'lzjb' 'gzip' 'gzip-1' 'gzip-2' 'gzip-3'
'gzip-4' 'gzip-5' 'gzip-6' 'gzip-7' 'gzip-8' 'gzip-9' 'zle')
typeset -a checksum_props=('on' 'off' 'fletcher2' 'fletcher4' 'sha256')
#
# Given the property array passed in, return 'num_props' elements to the
# user, excluding any elements below 'start.' This allows us to exclude
# 'off' and 'on' which can be either unwanted, or a duplicate of another
# property respectively.
#
function get_rand_prop
{
typeset prop_array=($(eval echo \${$1[@]}))
typeset -i num_props=$2
typeset -i start=$3
typeset retstr=""
[[ -z $prop_array || -z $num_props || -z $start ]] && \
log_fail "get_rand_prop: bad arguments"
typeset prop_max=$((${#prop_array[@]} - 1))
typeset -i i
for i in $($SHUF -i $start-$prop_max -n $num_props); do
retstr="${prop_array[$i]} $retstr"
done
echo $retstr
}
function get_rand_compress
{
get_rand_prop compress_props $1 2
}
function get_rand_compress_any
{
get_rand_prop compress_props $1 0
}
function get_rand_checksum
{
get_rand_prop checksum_props $1 2
}
function get_rand_checksum_any
{
get_rand_prop checksum_props $1 0
}
+1
View File
@@ -0,0 +1 @@
../../../zfs-script-config.sh
+1
View File
@@ -0,0 +1 @@
SUBDIRS = functional stress
@@ -0,0 +1,55 @@
SUBDIRS = \
acl \
atime \
bootfs \
cache \
cachefile \
casenorm \
clean_mirror \
cli_root \
cli_user \
compression \
ctime \
delegate \
devices \
exec \
features \
grow_pool \
grow_replicas \
history \
inheritance \
inuse \
large_files \
largest_pool \
link_count \
migration \
mmap \
mount \
mv_files \
nestedfs \
no_space \
nopwrite \
online_offline \
pool_names \
poolversion \
privilege \
quota \
redundancy \
refquota \
refreserv \
rename_dirs \
replacement \
reservation \
rootpool \
rsend \
scrub_mirror \
slog \
snapshot \
snapused \
sparse \
threadsappend \
truncate \
userquota \
write_dirs \
xattr \
zvol
@@ -0,0 +1,6 @@
pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/acl
dist_pkgdata_SCRIPTS = \
acl.cfg \
acl_common.kshlib
SUBDIRS = posix
@@ -0,0 +1,64 @@
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. $STF_SUITE/include/libtest.shlib
export NISSTAFILE=/var/tmp/nis_state
export TESTFILE=testfile$$
export TESTFILE0=testfile0.$$
export TESTFILE2=testfile2.$$
# Define super user 'zfstest'
export ZFS_ACL_ADMIN=zfstest
export ZFS_ACL_STAFF_GROUP=zfsgrp
export ZFS_ACL_STAFF1=staff1
export ZFS_ACL_STAFF2=staff2
export ZFS_ACL_OTHER_GROUP=othergrp
export ZFS_ACL_OTHER1=other1
export ZFS_ACL_OTHER2=other2
# Define the current user who run 'usr_exec'
export ZFS_ACL_CUR_USER=""
# Define global error string
export ZFS_ACL_ERR_STR=""
# Define test file and test directory which will be operated by chmod
export testfile=$TESTDIR/testfile
export testdir=$TESTDIR/testdir
# Define several directories for trivial ACLs function test.
export RES_DIR=$TESTDIR/RES
export INI_DIR=$TESTDIR/INIT
export TST_DIR=$TESTDIR/TEST
export TMP_DIR=$TESTDIR/TMP
# Define test files and their attributes files number for trivial
# ACLs function test
export NUM_FILE=5
export NUM_ATTR=10
@@ -0,0 +1,626 @@
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. $STF_SUITE/tests/functional/acl/acl.cfg
. $STF_SUITE/include/libtest.shlib
#
# Get the given file/directory access mode
#
# $1 object -- file or directroy
#
function get_mode #<obj>
{
typeset obj=$1
if (( ${#obj} == 0 )); then
return 1
fi
$LS -ld $obj | $AWK '{print $1}'
}
#
# Get the given file/directory ACL
#
# $1 object -- file or directroy
#
function get_acl #<obj>
{
typeset obj=$1
if (( ${#obj} == 0 )); then
return 1
fi
$LS -vd $obj | $NAWK '(NR != 1) {print $0}'
}
#
# Get the given file/directory ACL
#
# $1 object -- file or directroy
#
function get_compact_acl #<obj>
{
typeset obj=$1
if (( ${#obj} == 0 )); then
return 1
fi
$LS -Vd $obj | $NAWK '(NR != 1) {print $0}'
}
#
# Check the given two files/directories have the same ACLs
#
# Return 0, if source object acl is equal to target object acl.
#
# $1 source object
# $2 target object
#
function compare_acls #<src> <tgt>
{
typeset src=$1
typeset tgt=$2
(( ${#src} == 0 || ${#tgt} == 0 )) && return 1
[[ $src == $tgt ]] && return 0
typeset tmpsrc=/tmp/compare_acls.src.$$
typeset tmptgt=/tmp/compare_acls.tgt.$$
get_acl $src > $tmpsrc
get_acl $tgt > $tmptgt
typeset -i ret=0
$DIFF $tmpsrc $tmptgt > /dev/null 2>&1
ret=$?
$RM -f $tmpsrc $tmptgt
if (( ret != 0 )); then
return $ret
fi
get_compact_acl $src > $tmpsrc
get_compact_acl $tgt > $tmptgt
$DIFF $tmpsrc $tmptgt > /dev/null 2>&1
ret=$?
$RM -f $tmpsrc $tmptgt
return $ret
}
#
# Check that the given two objects have the same modes.
# Return 0, if their modes are equal with each other. Otherwise, return 1.
#
# $1 source object
# $2 target object
#
function compare_modes #<src> <tgt>
{
typeset src=$1
typeset tgt=$2
typeset -i i=0
set -A mode
(( ${#src} == 0 || ${#tgt} == 0 )) && return 1
[[ $src == $tgt ]] && return 0
typeset obj
for obj in $src $tgt
do
mode[i]=$(get_mode $obj)
(( i = i + 1 ))
done
[[ ${mode[0]} != ${mode[1]} ]] && return 1
return 0
}
#
# Check that the given two objects have the same xattrs.
# Return 0, if their xattrs are equal with each other. Otherwise, return 1.
#
# $1 source object
# $2 target object
#
function compare_xattrs #<src> <tgt>
{
typeset src=$1
typeset tgt=$2
(( ${#src} == 0 || ${#tgt} == 0 )) && return 1
[[ $src == $tgt ]] && return 0
typeset tmpsrc=/tmp/compare_xattrs.src.$$
typeset tmptgt=/tmp/compare_xattrs.tgt.$$
get_xattr $src > $tmpsrc
get_xattr $tgt > $tmptgt
typeset -i ret=0
$DIFF $tmpsrc $tmptgt > /dev/null 2>&1
ret=$?
$RM -f $tmpsrc $tmptgt
return $ret
}
#
# Check '+' is set for a given file/directory with 'ls [-l]' command
#
# $1 object -- file or directory.
#
function plus_sign_check_l #<obj>
{
typeset obj=$1
if (( ${#obj} == 0 )); then
return 1
fi
$LS -ld $obj | $AWK '{print $1}' | $GREP "+\>" > /dev/null
return $?
}
#
# Check '+' is set for a given file/directory with 'ls [-v]' command
#
# $1 object -- file or directory.
#
function plus_sign_check_v #<obj>
{
typeset obj=$1
if (( ${#obj} == 0 )); then
return 1
fi
$LS -vd $obj | $NAWK '(NR == 1) {print $1}' | $GREP "+\>" > /dev/null
return $?
}
#
# A wrapper function of c program
#
# $1 legal login name
# $2-n commands and options
#
function chgusr_exec #<login_name> <commands> [...]
{
$CHG_USR_EXEC $@
return $?
}
#
# Export the current user for the following usr_exec operating.
#
# $1 legal login name
#
function set_cur_usr #<login_name>
{
export ZFS_ACL_CUR_USER=$1
}
#
# Run commands by $ZFS_ACL_CUR_USER
#
# $1-n commands and options
#
function usr_exec #<commands> [...]
{
$CHG_USR_EXEC "$ZFS_ACL_CUR_USER" $@
return $?
}
#
# Count how many ACEs for the speficied file or directory.
#
# $1 file or directroy name
#
function count_ACE #<file or dir name>
{
if [[ ! -e $1 ]]; then
log_note "Need input file or directroy name."
return 1
fi
$LS -vd $1 | $NAWK 'BEGIN {count=0}
(NR != 1)&&(/[0-9]:/) {count++}
END {print count}'
return 0
}
#
# Get specified number ACE content of specified file or directory.
#
# $1 file or directory name
# $2 specified number
#
function get_ACE #<file or dir name> <specified number> <verbose|compact>
{
if [[ ! -e $1 || $2 -ge $(count_ACE $1) ]]; then
return 1
fi
typeset file=$1
typeset -i num=$2
typeset format=${3:-verbose}
typeset -i next_num=-1
typeset tmpfile=/tmp/tmp_get_ACE.$$
typeset line=""
typeset args
case $format in
verbose) args="-vd"
;;
compact) args="-Vd"
;;
*) log_fail "Invalid parameter as ($format), " \
"only verbose|compact is supported."
;;
esac
$LS $args $file > $tmpfile
(( $? != 0 )) && log_fail "FAIL: $LS $args $file > $tmpfile"
while read line; do
[[ -z $line ]] && continue
if [[ $args == -vd ]]; then
if [[ $line == "$num":* ]]; then
(( next_num = num + 1 ))
fi
if [[ $line == "$next_num":* ]]; then
break
fi
if (( next_num != -1 )); then
print -n $line
fi
else
if (( next_num == num )); then
print -n $line
fi
(( next_num += 1 ))
fi
done < $tmpfile
$RM -f $tmpfile
(( $? != 0 )) && log_fail "FAIL: $RM -f $tmpfile"
}
#
# Cleanup exist user/group.
#
function cleanup_user_group
{
del_user $ZFS_ACL_ADMIN
del_user $ZFS_ACL_STAFF1
del_user $ZFS_ACL_STAFF2
del_group $ZFS_ACL_STAFF_GROUP
del_user $ZFS_ACL_OTHER1
del_user $ZFS_ACL_OTHER2
del_group $ZFS_ACL_OTHER_GROUP
return 0
}
#
# Clean up testfile and test directory
#
function cleanup
{
if [[ -d $TESTDIR ]]; then
cd $TESTDIR
$RM -rf $TESTDIR/*
fi
}
#
# According to specified access or acl_spec, do relevant operating by using the
# specified user.
#
# $1 specified user
# $2 node
# $3 acl_spec or access
#
function rwx_node #user node acl_spec|access
{
typeset user=$1
typeset node=$2
typeset acl_spec=$3
if [[ $user == "" || $node == "" || $acl_spec == "" ]]; then
log_note "node or acl_spec are not defined."
return 1
fi
if [[ -d $node ]]; then
case $acl_spec in
*:read_data:*|read_data)
chgusr_exec $user $LS -l $node > /dev/null 2>&1
return $? ;;
*:write_data:*|write_data)
if [[ -f ${node}/tmpfile ]]; then
log_must $RM -f ${node}/tmpfile
fi
chgusr_exec $user $TOUCH ${node}/tmpfile > \
/dev/null 2>&1
return $? ;;
*"execute:"*|execute)
chgusr_exec $user $FIND $node > /dev/null 2>&1
return $? ;;
esac
else
case $acl_spec in
*:read_data:*|read_data)
chgusr_exec $user $CAT $node > /dev/null 2>&1
return $? ;;
*:write_data:*|write_data)
chgusr_exec $user $DD if=/usr/bin/ls of=$node > \
/dev/null 2>&1
return $? ;;
*"execute:"*|execute)
ZFS_ACL_ERR_STR=$(chgusr_exec $user $node 2>&1)
return $? ;;
esac
fi
}
#
# Get the given file/directory xattr
#
# $1 object -- file or directroy
#
function get_xattr #<obj>
{
typeset obj=$1
typeset xattr
if (( ${#obj} == 0 )); then
return 1
fi
for xattr in `$RUNAT $obj $LS | \
/usr/xpg4/bin/egrep -v -e SUNWattr_ro -e SUNWattr_rw` ; do
$RUNAT $obj $SUM $xattr
done
}
#
# Get the owner of a file/directory
#
function get_owner #node
{
typeset node=$1
typeset value
if [[ -z $node ]]; then
log_fail "node are not defined."
fi
if [[ -d $node ]]; then
value=$($LS -dl $node | $AWK '{print $3}')
elif [[ -e $node ]]; then
value=$($LS -l $node | $AWK '{print $3}')
fi
$ECHO $value
}
#
# Get the group of a file/directory
#
function get_group #node
{
typeset node=$1
typeset value
if [[ -z $node ]]; then
log_fail "node are not defined."
fi
if [[ -d $node ]]; then
value=$($LS -dl $node | $AWK '{print $4}')
elif [[ -e $node ]]; then
value=$($LS -l $node | $AWK '{print $4}')
fi
$ECHO $value
}
#
# Get the group name that a UID belongs to
#
function get_user_group #uid
{
typeset uid=$1
typeset value
if [[ -z $uid ]]; then
log_fail "UID not defined."
fi
value=$(id $uid)
if [[ $? -eq 0 ]]; then
value=${value##*\(}
value=${value%%\)*}
$ECHO $value
else
log_fail "Invalid UID (uid)."
fi
}
#
# Get the specified item of the specified string
#
# $1: Item number, count from 0.
# $2-n: strings
#
function getitem
{
typeset -i n=$1
shift
(( n += 1 ))
eval echo \${$n}
}
#
# This function calculate the specified directory files checksum and write
# to the specified array.
#
# $1 directory in which the files will be cksum.
# $2 file array name which was used to store file cksum information.
# $3 attribute array name which was used to store attribute information.
#
function cksum_files #<dir> <file_array_name> <attribute_array_name>
{
typeset dir=$1
typeset farr_name=$2
typeset aarr_name=$3
[[ ! -d $dir ]] && return
typeset oldpwd=$PWD
cd $dir
typeset files=$($LS file*)
typeset -i i=0
typeset -i n=0
while (( i < NUM_FILE )); do
typeset f=$(getitem $i $files)
eval $farr_name[$i]=\$\(\$CKSUM $f\)
typeset -i j=0
while (( j < NUM_ATTR )); do
eval $aarr_name[$n]=\$\(\$RUNAT \$f \$CKSUM \
attribute.$j\)
(( j += 1 ))
(( n += 1 ))
done
(( i += 1 ))
done
cd $oldpwd
}
#
# This function compare two cksum results array.
#
# $1 The array name which stored the cksum before operation.
# $2 The array name which stored the cksum after operation.
#
function compare_cksum #<array1> <array2>
{
typeset before=$1
typeset after=$2
eval typeset -i count=\${#$before[@]}
typeset -i i=0
while (( i < count )); do
eval typeset var1=\${$before[$i]}
eval typeset var2=\${$after[$i]}
if [[ $var1 != $var2 ]]; then
return 1
fi
(( i += 1 ))
done
return 0
}
#
# This function calculate all the files cksum information in current directory
# and output them to the specified file.
#
# $1 directory from which the files will be cksum.
# $2 cksum output file
#
function record_cksum #<outfile>
{
typeset dir=$1
typeset outfile=$2
[[ ! -d ${outfile%/*} ]] && usr_exec $MKDIR -p ${outfile%/*}
usr_exec cd $dir ; $FIND . -depth -type f -exec cksum {} \\\; | \
$SORT > $outfile
usr_exec cd $dir ; $FIND . -depth -type f -xattr -exec runat {} \
cksum attribute* \\\; | $SORT >> $outfile
}
#
# The function create_files creates the directories and files that the script
# will operate on to test extended attribute functionality.
#
# $1 The base directory in which to create directories and files.
#
function create_files #<directory>
{
typeset basedir=$1
[[ ! -d $basedir ]] && usr_exec $MKDIR -m 777 $basedir
[[ ! -d $RES_DIR ]] && usr_exec $MKDIR -m 777 $RES_DIR
[[ ! -d $INI_DIR ]] && usr_exec $MKDIR -m 777 $INI_DIR
[[ ! -d $TST_DIR ]] && usr_exec $MKDIR -m 777 $TST_DIR
[[ ! -d $TMP_DIR ]] && usr_exec $MKDIR -m 777 $TMP_DIR
#
# Create the original file and its attribute files.
#
[[ ! -a $RES_DIR/file ]] && \
usr_exec $FILE_WRITE -o create -f $RES_DIR/file \
-b 1024 -d 0 -c 1
[[ ! -a $RES_DIR/attribute ]] && \
usr_exec $CP $RES_DIR/file $RES_DIR/attribute
typeset oldpwd=$PWD
cd $INI_DIR
typeset -i i=0
while (( i < NUM_FILE )); do
typeset dstfile=$INI_DIR/file.$$.$i
usr_exec $CP $RES_DIR/file $dstfile
typeset -i j=0
while (( j < NUM_ATTR )); do
usr_exec $RUNAT $dstfile \
$CP $RES_DIR/attribute ./attribute.$j
(( j += 1 ))
done
(( i += 1 ))
done
cd $oldpwd
}
@@ -0,0 +1,6 @@
pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/acl/posix
dist_pkgdata_SCRIPTS = \
cleanup.ksh \
setup.ksh \
posix_001_pos.ksh \
posix_002_pos.ksh
+33
View File
@@ -0,0 +1,33 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/acl/acl_common.kshlib
cleanup_user_group
default_cleanup
@@ -0,0 +1,68 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. $STF_SUITE/include/libtest.shlib
#
# Copyright (c) 2012 by Delphix. All rights reserved.
#
#
# DESCRIPTION:
# Verify that user can access file/directory if acltype=posixacl.
#
# STRATEGY:
# 1. Test access to file (mode=rw-)
# a. Can modify file
# b. Can't create new file
# b. Can't execute file
#
verify_runnable "both"
log_assert "Verify acltype=posixacl works on file"
# Test access to FILE
log_note "Testing access to FILE"
log_must $TOUCH $TESTDIR/file.0
log_must $SETFACL -m g:zfsgrp:rw $TESTDIR/file.0
$GETFACL $TESTDIR/file.0 2> /dev/null | $EGREP -q "^group:zfsgrp:rw-$"
if [ "$?" -eq "0" ]; then
# Should be able to write to file
log_must $SU staff1 -c "$ECHO \"$ECHO test > /dev/null\" > $TESTDIR/file.0"
# Should NOT be able to create new file
log_mustnot $SU staff1 -c "$TOUCH $TESTDIR/file.1"
# Root should be able to run file, but not user
chmod +x $TESTDIR/file.0
log_must $TESTDIR/file.0
log_mustnot $SU staff1 -c $TESTDIR/file.0
log_pass "POSIX ACL mode works on files"
else
log_fail "Group 'zfsgrp' does not have 'rw' as specified"
fi
@@ -0,0 +1,62 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. $STF_SUITE/include/libtest.shlib
#
# Copyright (c) 2012 by Delphix. All rights reserved.
#
#
# DESCRIPTION:
# Verify that user can access file/directory if acltype=posixacl.
#
# STRATEGY:
# 1. Test access to directory (mode=-wx)
# a. Can create file in dir
# b. Can't list directory
#
verify_runnable "both"
log_assert "Verify acltype=posixacl works on directory"
# Test access to DIRECTORY
log_note "Testing access to DIRECTORY"
log_must $MKDIR $TESTDIR/dir.0
log_must $SETFACL -m g:zfsgrp:wx $TESTDIR/dir.0
$GETFACL $TESTDIR/dir.0 2> /dev/null | $EGREP -q "^group:zfsgrp:-wx$"
if [ "$?" -eq "0" ]; then
# Should be able to create file in directory
log_must $SU staff1 -c "$TOUCH $TESTDIR/dir.0/file.0"
# Should NOT be able to list files in directory
log_mustnot $SU staff1 -c "$LS -l $TESTDIR/dir.0"
log_pass "POSIX ACL mode works on directories"
else
log_fail "Group 'zfsgrp' does not have 'rwx' as specified"
fi
+48
View File
@@ -0,0 +1,48 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/acl/acl_common.kshlib
log_must $GETFACL --version
log_must $SETFACL --version
cleanup_user_group
# Create staff group and add user to it
log_must add_group $ZFS_ACL_STAFF_GROUP
log_must add_user $ZFS_ACL_STAFF_GROUP $ZFS_ACL_STAFF1
DISK=${DISKS%% *}
default_setup_noexit $DISK
log_must $CHMOD 777 $TESTDIR
# Use POSIX ACLs on filesystem
log_must $ZFS set acltype=posixacl $TESTPOOL/$TESTFS
log_must $ZFS set xattr=sa $TESTPOOL/$TESTFS
log_pass
@@ -0,0 +1,8 @@
pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/atime
dist_pkgdata_SCRIPTS = \
atime.cfg \
atime_common.kshlib \
cleanup.ksh \
setup.ksh \
atime_001_pos.ksh \
atime_002_neg.ksh
@@ -0,0 +1,30 @@
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
export TESTCLONE=testclone$$
export TESTSNAP=testsnap$$
export TESTFILE=testfile
+66
View File
@@ -0,0 +1,66 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. $STF_SUITE/tests/functional/atime/atime_common.kshlib
#
# DESCRIPTION:
# When atime=on, verify the access time for files is updated when read. It
# is available to fs and clone. To snapshot, it is unavailable.
#
# STRATEGY:
# 1. Create pool and fs.
# 2. Create '$TESTFILE' for fs.
# 3. Create snapshot and clone.
# 4. Setting atime=on on datasets except snapshot, and read '$TESTFILE'.
# 5. Expect the access time is updated on datasets except snapshot.
#
verify_runnable "both"
log_assert "Setting atime=on, the access time for files is updated when read."
log_onexit cleanup
#
# Create $TESTFILE, snapshot and clone.
#
setup_snap_clone
for dst in $TESTPOOL/$TESTFS $TESTPOOL/$TESTCLONE $TESTPOOL/$TESTFS@$TESTSNAP
do
typeset mtpt=$(get_prop mountpoint $dst)
if [[ $dst == $TESTPOOL/$TESTFS@$TESTSNAP ]]; then
mtpt=$(snapshot_mountpoint $dst)
log_mustnot check_atime_updated $mtpt/$TESTFILE
else
log_must $ZFS set atime=on $dst
log_must check_atime_updated $mtpt/$TESTFILE
fi
done
log_pass "Verify the property atime=on passed."
+67
View File
@@ -0,0 +1,67 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. $STF_SUITE/tests/functional/atime/atime_common.kshlib
#
# DESCRIPTION:
# When atime=off, verify the access time for files is not updated when read.
# It is available to pool, fs snapshot and clone.
#
# STRATEGY:
# 1. Create pool, fs.
# 2. Create '$TESTFILE' for fs.
# 3. Create snapshot and clone.
# 4. Setting atime=off on dataset and read '$TESTFILE'.
# 5. Verify the access time is not updated.
#
verify_runnable "both"
log_assert "Setting atime=off, the access time for files will not be updated \
when read."
log_onexit cleanup
#
# Create $TESTFILE, snapshot and clone.
#
setup_snap_clone
for dst in $TESTPOOL/$TESTFS $TESTPOOL/$TESTCLONE $TESTPOOL/$TESTFS@$TESTSNAP
do
typeset mtpt=$(get_prop mountpoint $dst)
if [[ $dst == $TESTPOOL/$TESTFS@$TESTSNAP ]]; then
mtpt=$(snapshot_mountpoint $dst)
else
log_must $ZFS set atime=off $dst
fi
log_mustnot check_atime_updated $mtpt/$TESTFILE
done
log_pass "Verify the property atime=off passed."
@@ -0,0 +1,78 @@
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. $STF_SUITE/tests/functional/atime/atime.cfg
. $STF_SUITE/include/libtest.shlib
#
# Check if the access time for specified file is updated.
#
# $1 Given an absolute path to a file name
#
# Return value:
# 0 -> The access time is updated.
# 1 -> The access time is not updated.
#
function check_atime_updated
{
typeset filename=$1
if is_linux; then
typeset before=$(stat -c %X $filename)
sleep 2
else
typeset before=$($LS -Eu $filename | $AWK '{print $7}')
fi
log_must $CAT $filename
if is_linux; then
typeset after=$(stat -c %X $filename)
else
typeset after=$($LS -Eu $filename | $AWK '{print $7}')
fi
if [[ $before != $after ]]; then
return 0
else
return 1
fi
}
function setup_snap_clone
{
# Create two file to verify snapshot.
log_must $TOUCH $TESTDIR/$TESTFILE
create_snapshot $TESTPOOL/$TESTFS $TESTSNAP
create_clone $TESTPOOL/$TESTFS@$TESTSNAP $TESTPOOL/$TESTCLONE
}
function cleanup
{
destroy_clone $TESTPOOL/$TESTCLONE
destroy_snapshot $TESTPOOL/$TESTFS@$TESTSNAP
}
+30
View File
@@ -0,0 +1,30 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. $STF_SUITE/include/libtest.shlib
default_cleanup
+31
View File
@@ -0,0 +1,31 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. $STF_SUITE/include/libtest.shlib
DISK=${DISKS%% *}
default_setup $DISK
@@ -0,0 +1,12 @@
pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/bootfs
dist_pkgdata_SCRIPTS = \
cleanup.ksh \
setup.ksh \
bootfs_001_pos.ksh \
bootfs_002_neg.ksh \
bootfs_003_pos.ksh \
bootfs_004_neg.ksh \
bootfs_005_neg.ksh \
bootfs_006_pos.ksh \
bootfs_007_neg.ksh \
bootfs_008_neg.ksh
+78
View File
@@ -0,0 +1,78 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# Copyright 2015 Nexenta Systems, Inc.
#
. $STF_SUITE/include/libtest.shlib
#
# DESCRIPTION:
#
# Valid datasets and snapshots are accepted as bootfs property values
#
# STRATEGY:
# 1. Create a set of datasets and snapshots in a test pool
# 2. Try setting them as boot filesystems
#
verify_runnable "global"
function cleanup {
if poolexists $TESTPOOL ; then
log_must $ZPOOL destroy $TESTPOOL
fi
if [[ -f $VDEV ]]; then
log_must $RM -f $VDEV
fi
}
$ZPOOL set 2>&1 | $GREP bootfs > /dev/null
if [ $? -ne 0 ]
then
log_unsupported "bootfs pool property not supported on this release."
fi
log_assert "Valid datasets are accepted as bootfs property values"
log_onexit cleanup
typeset VDEV=$TESTDIR/bootfs_001_pos_a.$$.dat
log_must $MKFILE 400m $VDEV
create_pool "$TESTPOOL" "$VDEV"
log_must $ZFS create $TESTPOOL/$TESTFS
log_must $ZFS snapshot $TESTPOOL/$TESTFS@snap
log_must $ZFS clone $TESTPOOL/$TESTFS@snap $TESTPOOL/clone
log_must $ZPOOL set bootfs=$TESTPOOL/$TESTFS $TESTPOOL
log_must $ZPOOL set bootfs=$TESTPOOL/$TESTFS@snap $TESTPOOL
log_must $ZPOOL set bootfs=$TESTPOOL/clone $TESTPOOL
log_must $ZFS promote $TESTPOOL/clone
log_must $ZPOOL set bootfs=$TESTPOOL/clone $TESTPOOL
log_pass "Valid datasets are accepted as bootfs property values"
+78
View File
@@ -0,0 +1,78 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# Copyright 2015 Nexenta Systems, Inc.
#
. $STF_SUITE/include/libtest.shlib
#
# DESCRIPTION:
#
# Invalid datasets are rejected as boot property values
#
# STRATEGY:
#
# 1. Create a zvol
# 2. Verify that we can't set the bootfs to that dataset
#
verify_runnable "global"
function cleanup {
if datasetexists $TESTPOOL/vol
then
log_must $ZFS destroy $TESTPOOL/vol
fi
if poolexists $TESTPOOL
then
log_must $ZPOOL destroy $TESTPOOL
fi
if [[ -f $VDEV ]]; then
log_must $RM -f $VDEV
fi
}
$ZPOOL set 2>&1 | $GREP bootfs > /dev/null
if [ $? -ne 0 ]
then
log_unsupported "bootfs pool property not supported on this release."
fi
log_assert "Invalid datasets are rejected as boot property values"
log_onexit cleanup
typeset VDEV=$TESTDIR/bootfs_002_neg_a.$$.dat
log_must $MKFILE 400m $VDEV
create_pool "$TESTPOOL" "$VDEV"
log_must $ZFS create -V 10m $TESTPOOL/vol
block_device_wait
log_mustnot $ZPOOL set bootfs=$TESTPOOL/vol $TESTPOOL
log_pass "Invalid datasets are rejected as boot property values"
+82
View File
@@ -0,0 +1,82 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. $STF_SUITE/include/libtest.shlib
#
# DESCRIPTION:
#
# Valid pool names are accepted
#
# STRATEGY:
# 1. Using a list of valid pool names
# 2. Create a filesystem in that pool
# 2. Verify we can set the bootfs to that filesystem
#
verify_runnable "global"
set -A pools "pool.$$" "pool123" "mypool"
function cleanup {
if poolexists $POOL ; then
log_must $ZPOOL destroy $POOL
fi
$RM /bootfs_003.$$.dat
}
$ZPOOL set 2>&1 | $GREP bootfs > /dev/null
if [ $? -ne 0 ]
then
log_unsupported "bootfs pool property not supported on this release."
fi
log_onexit cleanup
log_assert "Valid pool names are accepted by zpool set bootfs"
$MKFILE 64m $TESTDIR/bootfs_003.$$.dat
typeset -i i=0;
while [ $i -lt "${#pools[@]}" ]
do
POOL=${pools[$i]}
log_must $ZPOOL create $POOL $TESTDIR/bootfs_003.$$.dat
log_must $ZFS create $POOL/$TESTFS
log_must $ZPOOL set bootfs=$POOL/$TESTFS $POOL
RES=$($ZPOOL get bootfs $POOL | $TAIL -1 | $AWK '{print $3}' )
if [ $RES != "$POOL/$TESTFS" ]
then
log_fail "Expected $RES == $POOL/$TESTFS"
fi
log_must $ZPOOL destroy $POOL
i=$(( $i + 1 ))
done
log_pass "Valid pool names are accepted by zpool set bootfs"
+91
View File
@@ -0,0 +1,91 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. $STF_SUITE/include/libtest.shlib
#
# DESCRIPTION:
#
# Invalid pool names are rejected by zpool set bootfs
#
# STRATEGY:
# 1. Try to set bootfs on some non-existent pools
#
#
#
verify_runnable "global"
set -A pools "pool//$$" "pool%d123" "mirror" "c0t0d0s0" "pool*23*" "*po!l" \
"%s££%^"
function cleanup {
if poolexists $POOL; then
log_must $ZPOOL destroy $POOL
fi
$RM /bootfs_004.$$.dat
}
$ZPOOL set 2>&1 | $GREP bootfs > /dev/null
if [ $? -ne 0 ]
then
log_unsupported "bootfs pool property not supported on this release."
fi
log_assert "Invalid pool names are rejected by zpool set bootfs"
log_onexit cleanup
# here, we build up a large string and add it to the list of pool names
# a word to the ksh-wary, ${#array[@]} gives you the
# total number of entries in an array, so array[${#array[@]}]
# will index the last entry+1, ksh arrays start at index 0.
COUNT=0
while [ $COUNT -le 1025 ]
do
bigname="${bigname}o"
COUNT=$(( $COUNT + 1 ))
done
pools[${#pools[@]}]="$bigname"
$MKFILE 64m $TESTDIR/bootfs_004.$$.dat
typeset -i i=0;
while [ $i -lt "${#pools[@]}" ]
do
POOL=${pools[$i]}/$TESTFS
log_mustnot $ZPOOL create $POOL $TESTDIR/bootfs_004.$$.dat
log_mustnot $ZFS create $POOL/$TESTFS
log_mustnot $ZPOOL set bootfs=$POOL/$TESTFS $POOL
i=$(( $i + 1 ))
done
log_pass "Invalid pool names are rejected by zpool set bootfs"
+79
View File
@@ -0,0 +1,79 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/cli_root/zpool_upgrade/zpool_upgrade.kshlib
#
# DESCRIPTION:
#
# Boot properties cannot be set on pools with older versions
#
# STRATEGY:
# 1. Copy and import some pools of older versions
# 2. Create a filesystem on each
# 3. Verify that zpool set bootfs fails on each
#
verify_runnable "global"
function cleanup {
#
# we need destroy pools that created on top of $TESTPOOL first
#
typeset pool_name
for config in $CONFIGS; do
pool_name=$(eval $ECHO \$ZPOOL_VERSION_${config}_NAME)
if poolexists $pool_name; then
log_must $ZPOOL destroy $pool_name
fi
done
if poolexists $TESTPOOL ; then
log_must $ZPOOL destroy $TESTPOOL
fi
}
log_assert "Boot properties cannot be set on pools with older versions"
# These are configs from zpool_upgrade.cfg - see that file for more info.
CONFIGS="1 2 3"
log_onexit cleanup
log_must $ZPOOL create -f $TESTPOOL $DISKS
for config in $CONFIGS
do
create_old_pool $config
POOL_NAME=$(eval $ECHO \$ZPOOL_VERSION_${config}_NAME)
log_must $ZFS create $POOL_NAME/$TESTFS
log_mustnot $ZPOOL set bootfs=$POOL_NAME/$TESTFS $POOL_NAME
log_must destroy_upgraded_pool $config
done
log_pass "Boot properties cannot be set on pools with older versions"
+142
View File
@@ -0,0 +1,142 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. $STF_SUITE/include/libtest.shlib
#
# DESCRIPTION:
#
# Pools of correct vdev types accept boot property
#
# STRATEGY:
# 1. create pools of each vdev type (raid, raidz, raidz2, mirror + hotspares)
# 2. verify we can set bootfs on each pool type according to design
#
verify_runnable "global"
$ZPOOL set 2>&1 | $GREP bootfs > /dev/null
if [ $? -ne 0 ]
then
log_unsupported "bootfs pool property not supported on this release."
fi
VDEV1=$TESTDIR/bootfs_006_pos_a.$$.dat
VDEV2=$TESTDIR/bootfs_006_pos_b.$$.dat
VDEV3=$TESTDIR/bootfs_006_pos_c.$$.dat
VDEV4=$TESTDIR/bootfs_006_pos_d.$$.dat
function verify_bootfs { # $POOL
POOL=$1
log_must $ZFS create $POOL/$TESTFS
log_must $ZPOOL set bootfs=$POOL/$TESTFS $POOL
VAL=$($ZPOOL get bootfs $POOL | $TAIL -1 | $AWK '{print $3}' )
if [ $VAL != "$POOL/$TESTFS" ]
then
log_must $ZPOOL status -v $POOL
log_fail \
"set/get failed on $POOL - expected $VAL == $POOL/$TESTFS"
fi
log_must $ZPOOL destroy $POOL
}
function verify_no_bootfs { # $POOL
POOL=$1
log_must $ZFS create $POOL/$TESTFS
log_mustnot $ZPOOL set bootfs=$POOL/$TESTFS $POOL
VAL=$($ZPOOL get bootfs $POOL | $TAIL -1 | $AWK '{print $3}' )
if [ $VAL == "$POOL/$TESTFS" ]
then
log_must $ZPOOL status -v $POOL
log_fail "set/get unexpectedly failed $VAL != $POOL/$TESTFS"
fi
log_must $ZPOOL destroy $POOL
}
function cleanup {
if poolexists $TESTPOOL
then
log_must $ZPOOL destroy $TESTPOOL
fi
log_must $RM $VDEV1 $VDEV2 $VDEV3 $VDEV4
}
log_assert "Pools of correct vdev types accept boot property"
log_onexit cleanup
log_must $MKFILE 64m $VDEV1 $VDEV2 $VDEV3 $VDEV4
## the following configurations are supported bootable pools
# normal
log_must $ZPOOL create $TESTPOOL $VDEV1
verify_bootfs $TESTPOOL
# normal + hotspare
log_must $ZPOOL create $TESTPOOL $VDEV1 spare $VDEV2
verify_bootfs $TESTPOOL
# mirror
log_must $ZPOOL create $TESTPOOL mirror $VDEV1 $VDEV2
verify_bootfs $TESTPOOL
# mirror + hotspare
log_must $ZPOOL create $TESTPOOL mirror $VDEV1 $VDEV2 spare $VDEV3
verify_bootfs $TESTPOOL
## the following configurations are not supported as bootable pools
# stripe
log_must $ZPOOL create $TESTPOOL $VDEV1 $VDEV2
verify_no_bootfs $TESTPOOL
# stripe + hotspare
log_must $ZPOOL create $TESTPOOL $VDEV1 $VDEV2 spare $VDEV3
verify_no_bootfs $TESTPOOL
# raidz
log_must $ZPOOL create $TESTPOOL raidz $VDEV1 $VDEV2
verify_no_bootfs $TESTPOOL
# raidz + hotspare
log_must $ZPOOL create $TESTPOOL raidz $VDEV1 $VDEV2 spare $VDEV3
verify_no_bootfs $TESTPOOL
# raidz2
log_must $ZPOOL create $TESTPOOL raidz2 $VDEV1 $VDEV2 $VDEV3
verify_no_bootfs $TESTPOOL
# raidz2 + hotspare
log_must $ZPOOL create $TESTPOOL raidz2 $VDEV1 $VDEV2 $VDEV3 spare $VDEV4
verify_no_bootfs $TESTPOOL
log_pass "Pools of correct vdev types accept boot property"
+67
View File
@@ -0,0 +1,67 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. $STF_SUITE/include/libtest.shlib
#
# DESCRIPTION:
#
# Setting bootfs on a pool which was configured with the whole disk
# (i.e. EFI) will fail
#
# STRATEGY:
# 1. create a pool with a whole disk
# 2. create a filesystem on this pool
# 3. verify we can not set bootfs on the filesystem we just created.
#
verify_runnable "global"
function cleanup {
if poolexists $TESTPOOL ; then
destroy_pool "$TESTPOOL"
fi
}
log_onexit cleanup
DISK=${DISKS%% *}
typeset EFI_BOOTFS=$TESTPOOL/efs
typeset assert_mesg="setting bootfs on a pool which was configured with the \
whole disk will fail"
log_assert $assert_mesg
create_pool "$TESTPOOL" "$DISK"
log_must $ZFS create $EFI_BOOTFS
if is_linux; then
log_must $ZPOOL set bootfs=$EFI_BOOTFS $TESTPOOL
else
log_mustnot $ZPOOL set bootfs=$EFI_BOOTFS $TESTPOOL
fi
log_pass $assert_mesg
@@ -0,0 +1,65 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# Copyright 2015 Nexenta Systems, Inc.
#
. $STF_SUITE/include/libtest.shlib
#
# DESCRIPTION:
#
# Setting bootfs on a pool which was configured with the whole disk
# (i.e. EFI) works.
#
# STRATEGY:
# 1. create a pool with a whole disk
# 2. create a filesystem on this pool
# 3. verify we can set bootfs on the filesystem we just created.
#
verify_runnable "global"
function cleanup {
if poolexists $TESTPOOL ; then
destroy_pool "$TESTPOOL"
fi
}
log_onexit cleanup
DISK=${DISKS%% *}
typeset EFI_BOOTFS=$TESTPOOL/efs
typeset assert_mesg="setting bootfs on a pool which was configured with the \
whole disk works"
log_assert $assert_mesg
create_pool "$TESTPOOL" "$DISK"
log_must $ZFS create $EFI_BOOTFS
log_must $ZPOOL set bootfs=$EFI_BOOTFS $TESTPOOL
log_pass $assert_mesg
+78
View File
@@ -0,0 +1,78 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. $STF_SUITE/include/libtest.shlib
#
# DESCRIPTION:
#
# setting bootfs on a dataset which has gzip compression enabled will fail
#
# STRATEGY:
# 1. create pools based on a valid vdev
# 2. create a filesytem on this pool and set the compression property to gzip1-9
# 3. set the pool's bootfs property to filesystem we just configured which
# should fail
#
verify_runnable "global"
function cleanup {
if poolexists $TESTPOOL ; then
destroy_pool "$TESTPOOL"
fi
if [[ -f $VDEV ]]; then
log_must $RM -f $VDEV
fi
}
typeset assert_msg="setting bootfs on a dataset which has gzip \
compression enabled will fail"
typeset VDEV=$TESTDIR/bootfs_008_neg_a.$$.dat
typeset COMP_FS=$TESTPOOL/COMP_FS
log_onexit cleanup
log_assert $assert_msg
log_must $MKFILE 300m $VDEV
log_must $ZPOOL create $TESTPOOL $VDEV
log_must $ZFS create $COMP_FS
typeset -i i=0
set -A gtype "gzip" "gzip-1" "gzip-2" "gzip-3" "gzip-4" "gzip-5" \
"gzip-6" "gzip-7" "gzip-8" "gzip-9"
while (( i < ${#gtype[@]} )); do
log_must $ZFS set compression=${gtype[i]} $COMP_FS
log_mustnot $ZPOOL set bootfs=$COMP_FS $TESTPOOL
log_must $ZFS set compression=off $COMP_FS
(( i += 1 ))
done
log_pass $assert_msg
+34
View File
@@ -0,0 +1,34 @@
#! /bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2015 by Lawrence Livermore National Security, LLC
# All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
verify_runnable "global"
[[ -e $TESTDIR ]] && $RM -rf $TESTDIR
log_pass
+34
View File
@@ -0,0 +1,34 @@
#! /bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2015 by Lawrence Livermore National Security, LLC.
# All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
verify_runnable "global"
log_must $MKDIR $TESTDIR
log_pass
+17
View File
@@ -0,0 +1,17 @@
pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/cache
dist_pkgdata_SCRIPTS = \
cache.cfg \
cache.kshlib \
cleanup.ksh \
setup.ksh \
cache_001_pos.ksh \
cache_002_pos.ksh \
cache_003_pos.ksh \
cache_004_neg.ksh \
cache_005_neg.ksh \
cache_006_pos.ksh \
cache_007_neg.ksh \
cache_008_neg.ksh \
cache_009_pos.ksh \
cache_010_neg.ksh \
cache_011_pos.ksh
+70
View File
@@ -0,0 +1,70 @@
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#
# Copyright (c) 2013 by Delphix. All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
function set_disks
{
set -A disk_array $(find_disks $DISKS)
typeset -i DISK_ARRAY_NUM=0
if (( ${#disk_array[*]} <= 1 )); then
export DISK=${DISKS%% *}
else
export DISK=""
typeset -i i=0
while (( i < ${#disk_array[*]} )); do
export DISK${i}="${disk_array[$i]}"
DISKSARRAY="$DISKSARRAY ${disk_array[$i]}"
(( i = i + 1 ))
done
export DISK_ARRAY_NUM=$i
export DISKSARRAY
fi
if (( $DISK_ARRAY_NUM == 0 )); then
export disk=$DISK
else
export disk=$DISK0
fi
}
set_disks
export SIZE=64M
export VDIR=$TESTDIR/disk.cache
export VDIR2=$TESTDIR/disk2.cache
export VDEV="$VDIR/a $VDIR/b $VDIR/c"
export LDEV="$DISK0"
export VDEV2="$VDIR2/a $VDIR2/b $VDIR2/c"
export LDEV2="$DISK1"
+160
View File
@@ -0,0 +1,160 @@
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#
# Copyright (c) 2013 by Delphix. All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
function cleanup
{
if datasetexists $TESTPOOL ; then
log_must $ZPOOL destroy -f $TESTPOOL
fi
if datasetexists $TESTPOOL2 ; then
log_must $ZPOOL destroy -f $TESTPOOL2
fi
}
#
# Try zpool status/iostat for given pool
#
# $1 pool
#
function display_status
{
typeset pool=$1
typeset -i ret=0
$ZPOOL status -xv $pool > /dev/null 2>&1
ret=$?
$ZPOOL iostat > /dev/null 2>&1
((ret |= $?))
typeset mntpnt=$(get_prop mountpoint $pool)
$DD if=/dev/random of=$mntpnt/testfile.$$ &
typeset pid=$!
$ZPOOL iostat -v 1 3 > /dev/null
((ret |= $?))
kill -9 $pid
return $ret
}
#
# Verify the given cache device have correct type and status
#
# $1 pool name
# $2 device name
# $3 device status
# $4 device type
#
function verify_cache_device
{
typeset pool=$1
typeset device=$2
typeset status=$3
typeset type=$4
if [[ -z $pool || -z $device || -z $status ]]; then
log_fail "Usage: verify_cache_device <pool> <device> " \
"<status> [type]"
fi
if [[ $WRAPPER == *"smi"* ]]; then
$ECHO $device | $EGREP "^c[0-F]+([td][0-F]+)+$" > /dev/null 2>&1
if (( $? == 0 )); then
device=${device}s2
fi
fi
#
# Get all the cache devices and status table like below
#
# mirror:/disks/d ONLINE mirror:/disks/e ONLINE stripe:/disks/f ONLINE
#
set -A dev_stat_tab $($ZPOOL status -v $pool | $NAWK 'BEGIN {start=0} \
/\tcache/ {start=1}
/\tmirror/ || /\tspares/ || /^$/ {start=0}
(start==1) && /\t (\/|[a-zA-Z])/ \
{print "stripe:" $1 " " $2}
(start==1) && /\t (\/|[a-zA-Z])/ \
{print "mirror:" $1 " " $2}
# When hotspare is replacing
(start==1) && /\t (\/|[a-zA-Z])/ \
{print "mirror:" $1 " " $2}'
)
typeset -i i=0
typeset find=0
while (( i < ${#dev_stat_tab[@]} )); do
typeset dev=${dev_stat_tab[$i]}
typeset stat=${dev_stat_tab[((i+1))]}
case $dev in
stripe:$device)
if [[ "$type" == 'mirror' ]]; then
log_note "Unexpected type: mirror"
return 1
else
if [[ $stat != $status ]]; then
log_note "Status($stat) " \
"!= Expected stat($status)"
return 1
fi
return 0
fi
;;
mirror:$device)
if [[ -z "$type" || $type == 'stripe' ]]; then
log_note "Unexpected type: stripe"
return 1
else
if [[ $stat != $status ]]; then
log_note "Status($stat) " \
"!= Expected stat($status)"
return 1
fi
return 0
fi
;;
esac
((i += 2))
done
log_note "Can not find device: $device"
return 1
}
function verify_cache_support
{
$ZPOOL upgrade -v | $GREP "Cache devices" > /dev/null 2>&1
return $?
}

Some files were not shown because too many files have changed in this diff Show More