diff options
Diffstat (limited to 'tests')
10 files changed, 358 insertions, 1 deletions
diff --git a/tests/runfiles/linux.run b/tests/runfiles/linux.run index 7b51ef47b..7e4a5a7c3 100644 --- a/tests/runfiles/linux.run +++ b/tests/runfiles/linux.run @@ -59,7 +59,7 @@ tags = ['functional', 'cachefile'] # 'mixed_none_lookup', 'mixed_none_lookup_ci', 'mixed_none_delete', # 'mixed_formd_lookup', 'mixed_formd_lookup_ci', 'mixed_formd_delete'] [tests/functional/casenorm] -tests = ['case_all_values', 'norm_all_values'] +tests = ['case_all_values', 'norm_all_values', 'mixed_create_failure'] tags = ['functional', 'casenorm'] [tests/functional/channel_program/lua_core] @@ -475,6 +475,10 @@ tests = ['compress_001_pos', 'compress_002_pos', 'compress_003_pos', 'compress_004_pos'] tags = ['functional', 'compression'] +[tests/functional/cp_files] +tests = ['cp_files_001_pos'] +tags = ['functional', 'cp_files'] + [tests/functional/ctime] tests = ['ctime_001_pos' ] tags = ['functional', 'ctime'] diff --git a/tests/zfs-tests/tests/functional/Makefile.am b/tests/zfs-tests/tests/functional/Makefile.am index a5bbb36e0..6388f2d0f 100644 --- a/tests/zfs-tests/tests/functional/Makefile.am +++ b/tests/zfs-tests/tests/functional/Makefile.am @@ -13,6 +13,7 @@ SUBDIRS = \ cli_root \ cli_user \ compression \ + cp_files \ ctime \ deadman \ delegate \ diff --git a/tests/zfs-tests/tests/functional/casenorm/Makefile.am b/tests/zfs-tests/tests/functional/casenorm/Makefile.am index 65dd156e7..b284a2560 100644 --- a/tests/zfs-tests/tests/functional/casenorm/Makefile.am +++ b/tests/zfs-tests/tests/functional/casenorm/Makefile.am @@ -7,6 +7,7 @@ dist_pkgdata_SCRIPTS = \ insensitive_formd_lookup.ksh \ insensitive_none_delete.ksh \ insensitive_none_lookup.ksh \ + mixed_create_failure.ksh \ mixed_formd_delete.ksh \ mixed_formd_lookup_ci.ksh \ mixed_formd_lookup.ksh \ diff --git a/tests/zfs-tests/tests/functional/casenorm/mixed_create_failure.ksh b/tests/zfs-tests/tests/functional/casenorm/mixed_create_failure.ksh new file mode 100755 index 000000000..51b5bb3f6 --- /dev/null +++ b/tests/zfs-tests/tests/functional/casenorm/mixed_create_failure.ksh @@ -0,0 +1,136 @@ +#!/bin/ksh -p +# +# +# 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 2018 Nutanix Inc. All rights reserved. +# + +. $STF_SUITE/tests/functional/casenorm/casenorm.kshlib + +# DESCRIPTION: +# For the filesystem with casesensitivity=mixed, normalization=none, +# when multiple files with the same name (differing only in case) are created, +# the number of files is limited to what can fit in a fatzap leaf-block. +# And beyond that, it fails with ENOSPC. +# +# Ensure that the create/rename operations fail gracefully and not trigger an +# ASSERT. +# +# STRATEGY: +# Repeat the below steps for objects: files, directories, symlinks and hardlinks +# 1. Create objects with same name but varying in case. +# E.g. 'abcdefghijklmnop', 'Abcdefghijklmnop', 'ABcdefghijklmnop' etc. +# The create should fail with ENOSPC. +# 2. Create an object with name 'tmp_obj' and try to rename it to name that we +# failed to add in step 1 above. +# This should fail as well. + +verify_runnable "global" + +function cleanup +{ + destroy_testfs +} + +log_onexit cleanup +log_assert "With mixed mode: ensure create fails with ENOSPC beyond a certain limit" + +create_testfs "-o casesensitivity=mixed -o normalization=none" + +# Different object types +obj_type=('file' 'dir' 'symlink' 'hardlink') + +# Commands to create different object types +typeset -A ops +ops['file']='touch' +ops['dir']='mkdir' +ops['symlink']='ln -s' +ops['hardlink']='ln' + +# This function tests the following for a give object type : +# - Create multiple objects with the same name (varying only in case). +# Ensure that it eventually fails once the leaf-block limit is exceeded. +# - Create another object with a different name. And attempt rename it to the +# name (for which the create had failed in the previous step). +# This should fail as well. +# Args : +# $1 - object type (file/dir/symlink/hardlink) +# $2 - test directory +# +function test_ops +{ + typeset obj_type=$1 + typeset testdir=$2 + + target_obj='target-file' + + op="${ops[$obj_type]}" + + log_note "The op : $op" + log_note "testdir=$testdir obj_type=$obj_type" + + test_path="$testdir/$obj_type" + mkdir $test_path + log_note "Created test dir $test_path" + + if [[ $obj_type = "symlink" || $obj_type = "hardlink" ]]; then + touch $test_path/$target_obj + log_note "Created target: $test_path/$target_obj" + op="$op $test_path/$target_obj" + fi + + log_note "op : $op" + names='{a,A}{b,B}{c,C}{d,D}{e,E}{f,F}{g,G}{h,H}{i,I}{j,J}{k,K}{l,L}' + for name in $names; do + cmd="$op $test_path/$name" + out=$($cmd 2>&1) + ret=$? + log_note "cmd: $cmd ret: $ret out=$out" + if (($ret != 0)); then + if [[ $out = *@(No space left on device)* ]]; then + save_name="$test_path/$name" + break; + else + log_err "$cmd failed with unexpected error : $out" + fi + fi + done + + log_note 'Test rename \"sample_name\" rename' + TMP_OBJ="$test_path/tmp_obj" + cmd="$op $TMP_OBJ" + out=$($cmd 2>&1) + ret=$? + if (($ret != 0)); then + log_err "cmd:$cmd failed out:$out" + fi + + # Now, try to rename the tmp_obj to the name which we failed to add earlier. + # This should fail as well. + out=$(mv $TMP_OBJ $save_name 2>&1) + ret=$? + if (($ret != 0)); then + if [[ $out = *@(No space left on device)* ]]; then + log_note "$cmd failed as expected : $out" + else + log_err "$cmd failed with : $out" + fi + fi +} + +for obj_type in ${obj_type[*]}; +do + log_note "Testing create of $obj_type" + test_ops $obj_type $TESTDIR +done + +log_pass "Mixed mode FS: Ops on large number of colliding names fail gracefully" diff --git a/tests/zfs-tests/tests/functional/cp_files/.gitignore b/tests/zfs-tests/tests/functional/cp_files/.gitignore new file mode 100644 index 000000000..eac05e155 --- /dev/null +++ b/tests/zfs-tests/tests/functional/cp_files/.gitignore @@ -0,0 +1 @@ +/cp_files diff --git a/tests/zfs-tests/tests/functional/cp_files/Makefile.am b/tests/zfs-tests/tests/functional/cp_files/Makefile.am new file mode 100644 index 000000000..06c31f5f3 --- /dev/null +++ b/tests/zfs-tests/tests/functional/cp_files/Makefile.am @@ -0,0 +1,13 @@ +include $(top_srcdir)/config/Rules.am + +pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/cp_files + +dist_pkgdata_SCRIPTS = \ + cp_files_001_pos.ksh \ + cleanup.ksh \ + setup.ksh + +pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/cp_files + +pkgexec_PROGRAMS = cp_files +cp_files_SOURCES= cp_files.c diff --git a/tests/zfs-tests/tests/functional/cp_files/cleanup.ksh b/tests/zfs-tests/tests/functional/cp_files/cleanup.ksh new file mode 100755 index 000000000..3166bd6ec --- /dev/null +++ b/tests/zfs-tests/tests/functional/cp_files/cleanup.ksh @@ -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 2007 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 + +default_cleanup diff --git a/tests/zfs-tests/tests/functional/cp_files/cp_files.c b/tests/zfs-tests/tests/functional/cp_files/cp_files.c new file mode 100644 index 000000000..9af64a112 --- /dev/null +++ b/tests/zfs-tests/tests/functional/cp_files/cp_files.c @@ -0,0 +1,58 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <dirent.h> +#include <errno.h> +#include <string.h> + +int +main(int argc, char *argv[]) +{ + int tfd; + DIR *sdir; + struct dirent *dirent; + + if (argc != 3) { + fprintf(stderr, "Usage: %s SRC DST\n", argv[0]); + exit(1); + } + + sdir = opendir(argv[1]); + if (sdir == NULL) { + fprintf(stderr, "Failed to open %s: %s\n", + argv[1], strerror(errno)); + exit(2); + } + + tfd = open(argv[2], O_DIRECTORY); + if (tfd < 0) { + fprintf(stderr, "Failed to open %s: %s\n", + argv[2], strerror(errno)); + closedir(sdir); + exit(3); + } + + while ((dirent = readdir(sdir)) != NULL) { + if (dirent->d_name[0] == '.' && + (dirent->d_name[1] == '.' || dirent->d_name[1] == '\0')) + continue; + + int fd = openat(tfd, dirent->d_name, O_CREAT|O_WRONLY, 0666); + if (fd < 0) { + fprintf(stderr, "Failed to create %s/%s: %s\n", + argv[2], dirent->d_name, strerror(errno)); + closedir(sdir); + close(tfd); + exit(4); + } + close(fd); + } + + closedir(sdir); + close(tfd); + + return (0); +} diff --git a/tests/zfs-tests/tests/functional/cp_files/cp_files_001_pos.ksh b/tests/zfs-tests/tests/functional/cp_files/cp_files_001_pos.ksh new file mode 100755 index 000000000..3e138cfc9 --- /dev/null +++ b/tests/zfs-tests/tests/functional/cp_files/cp_files_001_pos.ksh @@ -0,0 +1,74 @@ +#! /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) 2018 by Nutanix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +# +# DESCRIPTION: +# Copy a large number of files between 2 directories +# within a zfs filesystem works without errors. +# This make sure zap upgrading and expanding works. +# +# STRATEGY: +# +# 1. Create NR_FILES files in directory src +# 2. Check the number of files is correct +# 3. Copy files from src to dst in readdir order +# 4. Check the number of files is correct +# + +verify_runnable "global" + +function cleanup +{ + rm -rf $TESTDIR/src $TESTDIR/dst +} + +log_assert "Copy a large number of files between 2 directories" \ + "within a zfs filesystem works without errors" + +log_onexit cleanup + +NR_FILES=60000 +BATCH=1000 + +log_must mkdir $TESTDIR/src +log_must mkdir $TESTDIR/dst + +WD=$(pwd) +cd $TESTDIR/src +# create NR_FILES in BATCH at a time to prevent overflowing argument buffer +for i in $(seq $(($NR_FILES/$BATCH))); do touch $(seq $((($i-1)*$BATCH+1)) $(($i*$BATCH))); done +cd $WD + +log_must test $NR_FILES -eq $(ls -U $TESTDIR/src | wc -l) + +# copy files from src to dst, use cp_files to make sure we copy in readdir order +log_must $STF_SUITE/tests/functional/cp_files/cp_files $TESTDIR/src $TESTDIR/dst + +log_must test $NR_FILES -eq $(ls -U $TESTDIR/dst | wc -l) + +log_pass diff --git a/tests/zfs-tests/tests/functional/cp_files/setup.ksh b/tests/zfs-tests/tests/functional/cp_files/setup.ksh new file mode 100755 index 000000000..fc5cec306 --- /dev/null +++ b/tests/zfs-tests/tests/functional/cp_files/setup.ksh @@ -0,0 +1,35 @@ +#!/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. +# + +# +# Copyright (c) 2013 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +DISK=${DISKS%% *} +default_setup $DISK |