lib/tst_mkfs: Clear first 512k of the device
PATCH v3 1/16 lib/tst_mkfs: Clear first 512k of the device
If we cal tst_mkfs() from a test more than once we end up with the very same bug we already fixed by clearing the device in tst_acquire_device(), i.e. some mkfs programs will not format it when there is a valid FS signature there. But we have to clear the device for the shell tests as well.
So this commit adds tst_clear_device() function that is both called from the tst_mkfs() and from the shell tst_device helper to clear up the first 512k of the device.
--- include/tst_device.h | 10 ++++++++++ lib/tst_device.c | 19 +++++++++++-------- lib/tst_mkfs.c | 4 ++++ testcases/lib/tst_device.c | 5 +++++ 4 files changed, 30 insertions(+), 8 deletions(-)
include/tst_device.h +10 -0
@@ -34,4 +34,14 @@ extern struct tst_device *tst_device;*/ int tst_umount (const char *path); +/* +* Clears a first few blocks of the device. This is needed when device has +* already been formatted with a filesystems, subset of mkfs.foo utils aborts +* the operation if it finds a filesystem signature there. +* +* Note that this is called from tst_mkfs() automatically, so you probably will +* not need to use this from the test yourself. +*/ +int tst_clear_device (const char *dev); +#endif /* TST_DEVICE_H__ */
lib/tst_device.c +11 -8
@@ -245,15 +245,8 @@ const char *tst_acquire_device__(unsigned int size) ltp_dev_size = ltp_dev_size/1024 /1024 ; -if (acq_dev_size <= ltp_dev_size) { -if (tst_fill_file (dev,0 ,1024 ,512 )) { -tst_resm (TWARN |TERRNO , -"Failed to clear the first 512k of %s" , - dev); - } - +if (acq_dev_size <= ltp_dev_size)return dev; - }tst_resm (TINFO ,"Skipping $LTP_DEV size %" PRIu64"MB, requested size %uMB" , ltp_dev_size, acq_dev_size);
@@ -319,6 +312,16 @@ int tst_release_device(const char *dev)return ret; } +int tst_clear_device (const char *dev) +{ +if (tst_fill_file (dev,0 ,1024 ,512 )) { +tst_resm (TWARN ,"Failed to clear 512k block on %s" , dev); +return 1 ; + } + +return 0 ; +} +int tst_umount (const char *path) {int err, ret, i;
lib/tst_mkfs.c +4 -0
@@ -18,6 +18,7 @@#include "test.h" #include "ltp_priv.h" #include "tst_mkfs.h" +#include "tst_device.h" #define OPTS_MAX 32
@@ -75,6 +76,9 @@ void tst_mkfs_(const char *file, const int lineno, void (cleanup_fn)(void), argv[pos] =NULL ; +if (tst_clear_device (dev)) +tst_brkm (TBROK , cleanup_fn,"tst_clear_device() failed" ); +tst_resm (TINFO ,"Formatting %s with %s opts='%s' extra opts='%s'" , dev, fs_type, fs_opts_str, extra_opt ? extra_opt :"" ); ret =tst_run_cmd (cleanup_fn, argv,"/dev/null" ,NULL ,1 );
testcases/lib/tst_device.c +5 -0
@@ -59,6 +59,11 @@ static int acquire_device(int argc, char *argv[])if (!device)return 1 ; +if (tst_clear_device (device)) { +tst_release_device (device); +return 1 ; + } +printf ("%s" , device);return 0 ;
Signature · 1 line
2.13.5
PATCH v3 1/16 lib/tst_mkfs: Clear first 512k of the device
Hi!
Ping?
Signature · 2 lines
Cyril Hrubis [email protected]
PATCH v3 1/16 lib/tst_mkfs: Clear first 512k of the device
----- Original Message -----
Quoted 2 lines
Hi!
Ping?
Hi,
The only changes against v2 are in last 2 patches we discussed, so no objections from me.
Regards,
Jan
Quoted 8 lines
--
Cyril Hrubis
[email protected]--
Mailing list info: https://lists.linux.it/listinfo/ltp
PATCH v3 1/16 lib/tst_mkfs: Clear first 512k of the device
Hi!
Quoted 2 lines
The only changes against v2 are in last 2 patches we discussed, so no objections from me.
Rebased and pushed, thanks for the review.
Signature · 2 lines
Cyril Hrubis [email protected]
PATCH v3 2/16 lib: Add interface to list supported filesystems
In reply to Cyril HrubisA filesystem is supported if kernel can mount it (we do not get ENODEV when we attempt to mount it) and if there is mkfs installed so that we can format a test device.
The function starts with a whitelist of filesystems to use and loops over them filtering out unsupported ones, then finally returns a list of filesystem that could be used for the testing.
--- include/tst_fs.h | 4 ++ lib/tst_supported_fs_types.c | 118 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 lib/tst_supported_fs_types.c
include/tst_fs.h +4 -0
@@ -146,6 +146,10 @@ int tst_get_path(const char *prog_name, char *buf, size_t buf_len);*/ int tst_fill_file (const char *path,char pattern,size_t bs,size_t bcount); +/* +* Returns NULL-terminated array of kernel-supported filesystems. +*/ +const char **tst_get_supported_fs_types (void );#ifdef TST_TEST_H__ static inline long tst_fs_type (const char *path)
lib/tst_supported_fs_types.c new file +118 -0
118 lines not on this page · raw message
Signature · 1 line
2.13.5
PATCH v3 2/16 lib: Add interface to list supported filesystems
Quoted 132 lines · Cyril Hrubis
A filesystem is supported if kernel can mount it (we do not get ENODEV when we attempt to mount it) and if there is mkfs installed so that we can format a test device.
The function starts with a whitelist of filesystems to use and loops over them filtering out unsupported ones, then finally returns a list of filesystem that could be used for the testing.
Signed-off-by Cyril Hrubis <[email protected]>--- include/tst_fs.h | 4 ++ lib/tst_supported_fs_types.c | 118 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 lib/tst_supported_fs_types.cinclude/tst_fs.h +4
-0@@ -146,6 +146,10 @@ int tst_get_path(const char *prog_name, char *buf, size_t buf_len);*/ int tst_fill_file (const char *path,char pattern,size_t bs,size_t bcount); +/* +* Returns NULL-terminated array of kernel-supported filesystems. +*/ +const char **tst_get_supported_fs_types (void );#ifdef TST_TEST_H__ static inline long tst_fs_type (const char *path)lib/tst_supported_fs_types.c new file +96
-0@@ -0,0 +1,118 @@ +/* +* Copyright (c) 2017 Cyril Hrubis <[email protected]> +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <sys/mount.h> +#include <sys/wait.h> + +#define TST_NO_DEFAULT_MAIN +#include "tst_test.h" +#include "tst_fs.h" + +static const char *const fs_type_whitelist[] = { +"ext2" , +"ext3" , +"ext4" , +"xfs" , +"btrfs" , +"vfat" , +"exfat" , +"ntfs" , +NULL +}; + +static const char *fs_types[ARRAY_SIZE (fs_type_whitelist)]; + +static int has_mkfs (const char *fs_type) +{ +char buf[128 ]; +int ret; + +sprintf (buf,"mkfs.%s >/dev/null 2>&1" , fs_type); + + ret =tst_system (buf); + +if (WEXITSTATUS (ret) ==127 ) { +tst_res (TINFO ,"mkfs.%s does not exist" , fs_type); +return 0 ; + } + +tst_res (TINFO ,"mkfs.%s does exist" , fs_type); +return 1 ; +} + +static int has_kernel_support (const char *fs_type) +{ +static int fuse_supported =-1 ; +const char *tmpdir =getenv ("TMPDIR" ); +char buf[128 ]; +int ret; + +if (!tmpdir) + tmpdir ="/tmp" ; + +mount ("/dev/zero" , tmpdir, fs_type,0 ,NULL ); +if (errno !=ENODEV ) { +tst_res (TINFO ,"Kernel supports %s" , fs_type); +return 1 ; + } + +/* Is FUSE supported by kernel? */ +if (fuse_supported ==-1 ) { + ret =open ("/dev/fuse" ,O_RDWR ); +if (ret <0 ) { + fuse_supported =0 ; + }else { + fuse_supported =1 ; +SAFE_CLOSE (ret); + } + } + +if (!fuse_supported) +return 0 ; + +/* Is FUSE implementation installed? */ +sprintf (buf,"mount.%s >/dev/null 2>&1" , fs_type); + + ret =tst_system (buf); +if (WEXITSTATUS (ret) ==127 ) { +tst_res (TINFO ,"Filesystem %s is not supported" , fs_type); +return 0 ;
lib/tst_supported_fs_types.c line 106
Quoted 10 lines
lib/tst_supported_fs_types.c new file +10
-0+ } + +tst_res (TINFO ,"FUSE does support %s" , fs_type); +return 1 ; +} + +static int is_supported (const char *fs_type) +{ +return has_kernel_support (fs_type) &&has_mkfs (fs_type); +}
It will be nice if this was an exported API as well.
Other than that, this is very useful for a bunch of tests that rely on formatting + mounting devices for error checks.
PATCH v3 3/16 SAFE_MOUNT: Handle FUSE mounts as well
In reply to Cyril HrubisFUSE mounts can be only mounted by the corresponding mount.$fs_type handler.
--- lib/safe_macros.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)
lib/safe_macros.c +39 -0
@@ -699,6 +699,23 @@ int safe_rename(const char *file, const int lineno, void (*cleanup_fn)(void),return rval; } +static const char *const fuse_fs_types[] = { +"exfat" , +"ntfs" , +}; + +static int is_fuse (const char *fs_type) +{ +unsigned int i; + +for (i =0 ; i <ARRAY_SIZE (fuse_fs_types); i++) { +if (!strcmp (fuse_fs_types[i], fs_type)) +return 1 ; + } + +return 0 ; +} + int safe_mount(const char *file, const int lineno, void (*cleanup_fn)(void), const char *source, const char *target, const char *filesystemtype, unsigned long mountflags,
@@ -708,6 +725,28 @@ int safe_mount(const char *file, const int lineno, void (*cleanup_fn)(void), rval =mount (source, target, filesystemtype, mountflags, data); +/* +* The FUSE filesystem executes mount.fuse helper, which tries to +* execute corresponding binary name which is encoded@the start of +* the source string and separated by # from the device name. +* +* The mount helpers are called mount.$fs_type. +*/ +if (rval ==-1 && errno ==ENODEV &&is_fuse (filesystemtype)) { +char buf[1024 ]; +int ret; + +tst_resm (TINFO ,"Trying FUSE..." ); +snprintf (buf,sizeof (buf),"mount.%s '%s' '%s'" , + filesystemtype, source, target); + + ret =tst_system (buf); +if (WIFEXITED (ret) &&WEXITSTATUS (ret) ==0 ) +return 0 ; + + errno =ENODEV ; + } +if (rval ==-1 ) { tst_brkm(TBROK | TERRNO, cleanup_fn, "%s:%d: mount(%s, %s, %s, %lu, %p) failed",
Signature · 1 line
2.13.5
PATCH v3 4/16 lib/tst_test: Add .all_filesystems flag
In reply to Cyril HrubisThis commit adds a support for re-runing a test on all available filesystems simply by turning on .all_filesystems flag in the tst_test structure.
The .all_filesystems flag implies .needs_device, the .format_filesystem and .mount_filesystem works as usuall but the device is formatted and mounted for each filesystem before we run the test function. The .setup and .cleanup functions are executed for each filesystem. The currently tested filesystem type is stored in the tst_device->fs_type.
This allows us to easily run a test that tests filesystem specific syscall for all supported filesystems without a need to hardcode all fs types into a runtest file and with a minimal changes to the test code.
--- include/tst_test.h | 9 +++++ lib/tst_test.c | 117 ++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 97 insertions(+), 29 deletions(-)
include/tst_test.h +9 -0
@@ -125,6 +125,15 @@ struct tst_test { int format_device:1; int mount_device:1; int needs_rofs:1; +/* +* If set the test function will be executed for all available +* filesystems and the current filesytem type would be set in the +* tst_device->fs_type. +* +* The test setup and cleanup are executed before/after __EACH__ call +* to the test function. +*/ + int all_filesystems:1;/* Minimal device size in megabytes */ unsigned int dev_min_size;
lib/tst_test.c +88 -29
174 lines not on this page · raw message
Signature · 1 line
2.13.5
PATCH v3 5/16 lib/tst_fs: Add tst_fill_fs()
In reply to Cyril HrubisAdds a simple helper to fill a filesystem.
All the funciton does is to create and write to files in a given directory until write() fails with ENOSPC.
This is intended to be used in various filesystem related tests such as fallocate and stress tests.
--- include/tst_fs.h | 5 +++++ lib/tst_fill_fs.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 lib/tst_fill_fs.c
include/tst_fs.h +5 -0
@@ -151,6 +151,11 @@ int tst_fill_file(const char *path, char pattern, size_t bs, size_t bcount);*/ const char **tst_get_supported_fs_types (void ); +/* +* Creates and writes to files on given path until write fails with ENOSPC +*/ +void tst_fill_fs (const char *path,int verbose); +#ifdef TST_TEST_H__ static inline long tst_fs_type (const char *path) {
lib/tst_fill_fs.c new file +63 -0
63 lines not on this page · raw message
Signature · 1 line
2.13.5
PATCH v3 5/16 lib/tst_fs: Add tst_fill_fs()
Quoted 3 lines · Cyril Hrubis
Adds a simple helper to fill a filesystem.
All the funciton does is to create and write to files in a given
s/funciton/function
Quoted 4 lines
directory until
write()fails with ENOSPC.This is intended to be used in various filesystem related tests such as fallocate and stress tests.
Couple of other use cases
- To fill a filesystem would be to create nested directories for EMLINK testing in order to test file system limit(s) (e.g. syscalls/mkdir)
- Filling a filesystem with empty files (e.g syscalls/rename etc )
That said, the function can be expanded to do this at a later time as well based on the function parameters.
Quoted 83 lines
Signed-off-by Cyril Hrubis <[email protected]>--- include/tst_fs.h | 5 +++++ lib/tst_fill_fs.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 lib/tst_fill_fs.cinclude/tst_fs.h +5
-0@@ -151,6 +151,11 @@ int tst_fill_file(const char *path, char pattern, size_t bs, size_t bcount);*/ const char **tst_get_supported_fs_types (void ); +/* +* Creates and writes to files on given path until write fails with ENOSPC +*/ +void tst_fill_fs (const char *path,int verbose); +#ifdef TST_TEST_H__ static inline long tst_fs_type (const char *path) {lib/tst_fill_fs.c new file +53
-0@@ -0,0 +1,63 @@ +/* +* Copyright (c) 2017 Cyril Hrubis <[email protected]> +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +#define TST_NO_DEFAULT_MAIN +#include "tst_test.h" +#include "tst_fs.h" + +void tst_fill_fs (const char *path,int verbose) +{ +int i =0 ; +char file[PATH_MAX ]; +char buf[4096 ]; +size_t len; +ssize_t ret; +int fd; + +for (;;) { + len =random () % (1024 *102400 ); + +snprintf (file,sizeof (file),"%s/file%i" , path, i++); + +if (verbose) +tst_res (TINFO ,"Creating file %s size %zu" , file, len); + + fd =SAFE_OPEN (file,O_WRONLY |O_CREAT ,0700 ); + +while (len) { + ret =write (fd, buf,MIN (len,sizeof (buf))); + +if (ret <0 ) { +SAFE_CLOSE (fd); + +if (errno !=ENOSPC ) +tst_brk (TBROK |TERRNO ,"write()" ); +
lib/tst_fill_fs.c line 63
Quoted 10 lines
lib/tst_fill_fs.c new file +10
-0+tst_res (TINFO |TERRNO ,"write()" ); +return ; + } + + len -= ret; + } + +SAFE_CLOSE (fd); + } +}
Quoted 6 lines
Signature · 5 lines
2.13.5 -- Mailing list info: https://lists.linux.it/listinfo/ltp
PATCH v3 6/16 syscalls/fallocate05: New test
In reply to Cyril HrubisTests that fallocate() works fine when filesystem is full.
--- runtest/syscalls | 1 + testcases/kernel/syscalls/.gitignore | 1 + testcases/kernel/syscalls/fallocate/fallocate05.c | 104 ++++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 testcases/kernel/syscalls/fallocate/fallocate05.c
runtest/syscalls +1 -0
@@ -160,6 +160,7 @@ fallocate01 fallocate01 fallocate02 fallocate02 fallocate03 fallocate03 fallocate04 fallocate04 +fallocate05 fallocate05 #posix_fadvise test cases posix_fadvise01 posix_fadvise01
testcases/kernel/syscalls/.gitignore +1 -0
@@ -141,6 +141,7 @@ /fallocate/fallocate02 /fallocate/fallocate03 /fallocate/fallocate04 +/fallocate/fallocate05 /fchdir/fchdir01 /fchdir/fchdir02 /fchdir/fchdir03
testcases/kernel/syscalls/fallocate/fallocate05.c new file +104 -0
104 lines not on this page · raw message
Signature · 1 line
2.13.5
PATCH v3 7/16 syscalls/msync04: Run test for all filesystems
In reply to Cyril Hrubis--- testcases/kernel/syscalls/msync/msync04.c | 1 + 1 file changed, 1 insertion(+)
testcases/kernel/syscalls/msync/msync04.c +1 -0
@@ -109,5 +109,6 @@ static struct tst_test test = { .needs_root = 1, .mntpoint = "msync04", .mount_device = 1, + .all_filesystems = 1, .min_kver = "2.6.25", };
Signature · 1 line
2.13.5
PATCH v3 8/16 syscalls/fallocate04: Convert to the new library
In reply to Cyril Hrubis--- testcases/kernel/syscalls/fallocate/fallocate04.c | 169 ++++++++++------------ 1 file changed, 77 insertions(+), 92 deletions(-)
testcases/kernel/syscalls/fallocate/fallocate04.c +77 -92
@@ -30,13 +30,9 @@#include <fcntl.h> #include <unistd.h> -#include "test.h" -#include "safe_macros.h" +#include "tst_test.h" #include "lapi/fallocate.h" -char *TCID ="fallocate04" ; -int TST_TOTAL =5 ; -static int fd;static const char fname[] ="fallocate04.txt" ;static size_t block_size;
@@ -44,28 +40,18 @@ static size_t buf_size;#define NUM_OF_BLOCKS 3 -static int verbose; -static const option_t options[] = { - {"v" , &verbose,NULL }, - {NULL ,NULL ,NULL } -}; - -static void help (void ) -{ -printf (" -v Verbose\n" ); -} +static char *verbose;static void cleanup (void ) { -close (fd); -tst_rmdir (); +SAFE_CLOSE (fd); }static void get_blocksize (void ) {struct stat file_stat; -SAFE_FSTAT (cleanup, fd, &file_stat); +SAFE_FSTAT (fd, &file_stat); block_size = file_stat.st_blksize; buf_size =NUM_OF_BLOCKS * block_size;
@@ -77,7 +63,7 @@ static size_t get_allocsize(void)fsync (fd); -SAFE_FSTAT (cleanup, fd, &file_stat); +SAFE_FSTAT (fd, &file_stat);return file_stat.st_blocks *512 ; }
@@ -93,9 +79,7 @@ static void fill_tst_buf(char buf[])static void setup (void ) { -tst_tmpdir (); - - fd =SAFE_OPEN (cleanup, fname,O_RDWR |O_CREAT ,0700 ); + fd =SAFE_OPEN (fname,O_RDWR |O_CREAT ,0700 );get_blocksize (); }
@@ -104,86 +88,86 @@ static void check_file_data(const char exp_buf[], size_t size) {char rbuf[size]; -tst_resm (TINFO ,"reading the file, compare with expected buffer" ); +tst_res (TINFO ,"reading the file, compare with expected buffer" ); -SAFE_LSEEK (cleanup, fd,0 ,SEEK_SET ); -SAFE_READ (cleanup,1 , fd, rbuf, size); +SAFE_LSEEK (fd,0 ,SEEK_SET ); +SAFE_READ (1 , fd, rbuf, size);if (memcmp (exp_buf, rbuf, size)) {if (verbose) { -tst_resm_hexd (TINFO , exp_buf, size,"expected:" ); -tst_resm_hexd (TINFO , rbuf, size,"but read:" ); +tst_res_hexd (TINFO , exp_buf, size,"expected:" ); +tst_res_hexd (TINFO , rbuf, size,"but read:" ); } -tst_brkm (TFAIL , cleanup,"not expected file data" ); +tst_brk (TFAIL ,"not expected file data" ); } }static void test01 (void ) { -tst_resm (TINFO ,"allocate '%zu' bytes" , buf_size); +tst_res (TINFO ,"allocate '%zu' bytes" , buf_size);if (fallocate (fd,0 ,0 , buf_size) ==-1 ) {if (errno ==ENOSYS || errno ==EOPNOTSUPP ) -tst_brkm (TCONF , cleanup,"fallocate() not supported" ); -tst_brkm (TFAIL |TERRNO , cleanup,"fallocate() failed" ); +tst_brk (TCONF ,"fallocate() not supported" ); +tst_brk (TFAIL |TERRNO ,"fallocate() failed" ); }char buf[buf_size];fill_tst_buf (buf); -SAFE_WRITE (cleanup,1 , fd, buf, buf_size); +SAFE_WRITE (1 , fd, buf, buf_size); -tst_resm (TPASS ,"test-case succeeded" ); +tst_res (TPASS ,"test-case succeeded" ); }static void test02 (void ) {size_t alloc_size0 =get_allocsize (); -tst_resm (TINFO ,"read allocated file size '%zu'" , alloc_size0); -tst_resm (TINFO ,"make a hole with FALLOC_FL_PUNCH_HOLE" ); +tst_res (TINFO ,"read allocated file size '%zu'" , alloc_size0); +tst_res (TINFO ,"make a hole with FALLOC_FL_PUNCH_HOLE" );if (tst_kvercmp (2 ,6 ,38 ) <0 ) { -tst_brkm (TCONF , cleanup, -"FALLOC_FL_PUNCH_HOLE needs Linux 2.6.38 or newer" ); +tst_brk (TCONF , +"FALLOC_FL_PUNCH_HOLE needs Linux 2.6.38 or newer" ); }if (fallocate (fd,FALLOC_FL_PUNCH_HOLE |FALLOC_FL_KEEP_SIZE , block_size, block_size) ==-1 ) {if (errno ==EOPNOTSUPP ) { -tst_brkm (TCONF , cleanup, -"FALLOC_FL_PUNCH_HOLE not supported" ); +tst_brk (TCONF , +"FALLOC_FL_PUNCH_HOLE not supported" ); } -tst_brkm (TFAIL |TERRNO , cleanup,"fallocate() failed" ); +tst_brk (TFAIL |TERRNO ,"fallocate() failed" ); } -tst_resm (TINFO ,"check that file has a hole with lseek(,,SEEK_HOLE)" ); +tst_res (TINFO ,"check that file has a hole with lseek(,,SEEK_HOLE)" );off_t ret =lseek (fd,0 ,SEEK_HOLE );if (ret != (ssize_t )block_size) {/* exclude error when kernel doesn't have SEEK_HOLE support */ if (errno !=EINVAL ) { -tst_brkm (TFAIL |TERRNO , cleanup, +tst_brk (TFAIL |TERRNO ,"fallocate() or lseek() failed" ); }if (tst_kvercmp (3 ,1 ,0 ) <0 ) { -tst_resm (TINFO ,"lseek() doesn't support SEEK_HOLE, " +tst_res (TINFO ,"lseek() doesn't support SEEK_HOLE, " "this is expected for < 3.1 kernels" ); }else { -tst_brkm (TBROK |TERRNO , cleanup, +tst_brk (TBROK |TERRNO ,"lseek() doesn't support SEEK_HOLE" ); } }else { -tst_resm (TINFO ,"found a hole at '%ld' offset" , ret); +tst_res (TINFO ,"found a hole@'%ld' offset" , ret); }size_t alloc_size1 =get_allocsize (); -tst_resm (TINFO ,"allocated file size before '%zu' and after '%zu'" , +tst_res (TINFO ,"allocated file size before '%zu' and after '%zu'" , alloc_size0, alloc_size1);if ((alloc_size0 - block_size) != alloc_size1) -tst_brkm (TFAIL , cleanup,"not expected allocated size" ); +tst_brk (TFAIL ,"not expected allocated size" );char exp_buf[buf_size];
@@ -192,29 +176,29 @@ static void test02(void)check_file_data (exp_buf, buf_size); -tst_resm (TPASS ,"test-case succeeded" ); +tst_res (TPASS ,"test-case succeeded" ); }static void test03 (void ) { -tst_resm (TINFO ,"zeroing file space with FALLOC_FL_ZERO_RANGE" ); +tst_res (TINFO ,"zeroing file space with FALLOC_FL_ZERO_RANGE" );if (tst_kvercmp (3 ,15 ,0 ) <0 ) { -tst_brkm (TCONF , cleanup, -"FALLOC_FL_ZERO_RANGE needs Linux 3.15 or newer" ); +tst_brk (TCONF , +"FALLOC_FL_ZERO_RANGE needs Linux 3.15 or newer" ); }size_t alloc_size0 =get_allocsize (); -tst_resm (TINFO ,"read current allocated file size '%zu'" , alloc_size0); +tst_res (TINFO ,"read current allocated file size '%zu'" , alloc_size0);if (fallocate (fd,FALLOC_FL_ZERO_RANGE , block_size -1 , block_size +2 ) ==-1 ) {if (errno ==EOPNOTSUPP ) { -tst_brkm (TCONF , cleanup, -"FALLOC_FL_ZERO_RANGE not supported" ); +tst_brk (TCONF , +"FALLOC_FL_ZERO_RANGE not supported" ); } -tst_brkm (TFAIL |TERRNO , cleanup,"fallocate failed" ); +tst_brk (TFAIL |TERRNO ,"fallocate failed" ); }/* The file hole in the specified range must be allocated and
@@ -222,10 +206,10 @@ static void test03(void)*/ size_t alloc_size1 =get_allocsize (); -tst_resm (TINFO ,"allocated file size before '%zu' and after '%zu'" , +tst_res (TINFO ,"allocated file size before '%zu' and after '%zu'" , alloc_size0, alloc_size1);if ((alloc_size0 + block_size) != alloc_size1) -tst_brkm (TFAIL , cleanup,"not expected allocated size" ); +tst_brk (TFAIL ,"not expected allocated size" );char exp_buf[buf_size];
@@ -234,32 +218,32 @@ static void test03(void)check_file_data (exp_buf, buf_size); -tst_resm (TPASS ,"test-case succeeded" ); +tst_res (TPASS ,"test-case succeeded" ); }static void test04 (void ) { -tst_resm (TINFO ,"collapsing file space with FALLOC_FL_COLLAPSE_RANGE" ); +tst_res (TINFO ,"collapsing file space with FALLOC_FL_COLLAPSE_RANGE" );size_t alloc_size0 =get_allocsize (); -tst_resm (TINFO ,"read current allocated file size '%zu'" , alloc_size0); +tst_res (TINFO ,"read current allocated file size '%zu'" , alloc_size0);if (fallocate (fd,FALLOC_FL_COLLAPSE_RANGE , block_size, block_size) ==-1 ) {if (errno ==EOPNOTSUPP ) { -tst_brkm (TCONF , cleanup, -"FALLOC_FL_COLLAPSE_RANGE not supported" ); +tst_brk (TCONF , +"FALLOC_FL_COLLAPSE_RANGE not supported" ); } -tst_brkm (TFAIL |TERRNO , cleanup,"fallocate failed" ); +tst_brk (TFAIL |TERRNO ,"fallocate failed" ); }size_t alloc_size1 =get_allocsize (); -tst_resm (TINFO ,"allocated file size before '%zu' and after '%zu'" , +tst_res (TINFO ,"allocated file size before '%zu' and after '%zu'" , alloc_size0, alloc_size1);if ((alloc_size0 - block_size) != alloc_size1) -tst_brkm (TFAIL , cleanup,"not expected allocated size" ); +tst_brk (TFAIL ,"not expected allocated size" );size_t size = buf_size - block_size;char tmp_buf[buf_size];
@@ -274,36 +258,36 @@ static void test04(void) exp_buf[block_size -1 ] = exp_buf[block_size] ='\0' ;check_file_data (exp_buf, size); -tst_resm (TPASS ,"test-case succeeded" ); +tst_res (TPASS ,"test-case succeeded" ); }static void test05 (void ) { -tst_resm (TINFO ,"inserting space with FALLOC_FL_INSERT_RANGE" ); +tst_res (TINFO ,"inserting space with FALLOC_FL_INSERT_RANGE" );size_t alloc_size0 =get_allocsize (); -tst_resm (TINFO ,"read current allocated file size '%zu'" , alloc_size0); +tst_res (TINFO ,"read current allocated file size '%zu'" , alloc_size0);if (fallocate (fd,FALLOC_FL_INSERT_RANGE , block_size, block_size) ==-1 ) {if (errno ==EOPNOTSUPP ) { -tst_brkm (TCONF , cleanup, -"FALLOC_FL_INSERT_RANGE not supported" ); +tst_brk (TCONF , +"FALLOC_FL_INSERT_RANGE not supported" ); } -tst_brkm (TFAIL |TERRNO , cleanup,"fallocate failed" ); +tst_brk (TFAIL |TERRNO ,"fallocate failed" ); }/* allocate space and ensure that it filled with zeroes */ if (fallocate (fd,FALLOC_FL_ZERO_RANGE , block_size, block_size) ==-1 ) -tst_brkm (TFAIL |TERRNO , cleanup,"fallocate failed" ); +tst_brk (TFAIL |TERRNO ,"fallocate failed" );size_t alloc_size1 =get_allocsize (); -tst_resm (TINFO ,"allocated file size before '%zu' and after '%zu'" , +tst_res (TINFO ,"allocated file size before '%zu' and after '%zu'" , alloc_size0, alloc_size1);if ((alloc_size0 + block_size) != alloc_size1) -tst_brkm (TFAIL , cleanup,"not expected allocated size" ); +tst_brk (TFAIL ,"not expected allocated size" );char exp_buf[buf_size];
@@ -312,26 +296,27 @@ static void test05(void)check_file_data (exp_buf, buf_size); -tst_resm (TPASS ,"test-case succeeded" ); +tst_res (TPASS ,"test-case succeeded" ); } -int main (int argc,char *argv[]) +static void run (void ) { -int lc; - -tst_parse_opts (argc, argv, options, help); - -setup (); - -for (lc =0 ;TEST_LOOPING (lc); ++lc) { -test01 (); -test02 (); -test03 (); -test04 (); -test05 (); - } +test01 (); +test02 (); +test03 (); +test04 (); +test05 (); +} -cleanup (); +static struct tst_option opts[] = { + {"v" , &verbose,"-v Turns on verbose mode" }, + {NULL ,NULL ,NULL } +}; -tst_exit (); -} +static struct tst_test test = { + .options = opts, + .setup = setup, + .cleanup = cleanup, + .test_all = run, + .needs_tmpdir =1 , +};
Signature · 1 line
2.13.5
PATCH v3 9/16 syscalls/fallocate04: Run test for all filesystems
In reply to Cyril Hrubis--- testcases/kernel/syscalls/fallocate/fallocate04.c | 49 +++++++++++++---------- 1 file changed, 28 insertions(+), 21 deletions(-)
testcases/kernel/syscalls/fallocate/fallocate04.c +28 -21
@@ -34,19 +34,15 @@#include "lapi/fallocate.h" static int fd; -static const char fname[] ="fallocate04.txt" ;static size_t block_size;static size_t buf_size; +#define MNTPOINT "fallocate" +#define FNAME MNTPOINT "/fallocate.txt"#define NUM_OF_BLOCKS 3static char *verbose; -static void cleanup (void ) -{ -SAFE_CLOSE (fd); -} -static void get_blocksize (void ) {struct stat file_stat;
@@ -77,13 +73,6 @@ static void fill_tst_buf(char buf[])memset (buf + i * block_size,'a' + i, block_size); } -static void setup (void ) -{ - fd =SAFE_OPEN (fname,O_RDWR |O_CREAT ,0700 ); - -get_blocksize (); -} -static void check_file_data (const char exp_buf[],size_t size) {char rbuf[size];
@@ -299,13 +288,26 @@ static void test05(void)tst_res (TPASS ,"test-case succeeded" ); } -static void run (void ) +static void (*tcases[])(void ) = { + test01, test02, test03, test04, test05 +}; + +static void run (unsigned int i) +{ + tcases[i](); +} + +static void setup (void ) +{ + fd =SAFE_OPEN (FNAME ,O_RDWR |O_CREAT ,0700 ); + +get_blocksize (); +} + +static void cleanup (void ) { -test01 (); -test02 (); -test03 (); -test04 (); -test05 (); +if (fd >0 ) +SAFE_CLOSE (fd); }static struct tst_option opts[] = {
@@ -315,8 +317,13 @@ static struct tst_option opts[] = {static struct tst_test test = { .options = opts, - .setup = setup, .cleanup = cleanup, - .test_all = run, + .setup = setup, + .test = run, + .tcnt =ARRAY_SIZE (tcases), + .mount_device =1 , + .mntpoint =MNTPOINT , + .all_filesystems =1 , .needs_tmpdir =1 , + .needs_root =1 , };
Signature · 1 line
2.13.5
PATCH v3 10/16 syscalls/setxattr01: Convert to the new library.
In reply to Cyril Hrubis--- testcases/kernel/syscalls/setxattr/setxattr01.c | 138 +++++++++--------------- 1 file changed, 51 insertions(+), 87 deletions(-)
testcases/kernel/syscalls/setxattr/setxattr01.c +51 -87
@@ -57,10 +57,7 @@#ifdef HAVE_SYS_XATTR_H # include <sys/xattr.h> #endif -#include "test.h" -#include "safe_macros.h" - -char *TCID ="setxattr01" ; +#include "tst_test.h" #ifdef HAVE_SYS_XATTR_H #define XATTR_NAME_MAX 255
@@ -69,157 +66,124 @@ char *TCID = "setxattr01";#define XATTR_TEST_KEY "user.testkey"#define XATTR_TEST_VALUE "this is a test value"#define XATTR_TEST_VALUE_SIZE 20 +#define FNAME "setxattr01testfile" -static void setup (void ); -static void cleanup (void ); - -char filename[BUFSIZ ]; -char long_key[XATTR_NAME_LEN ]; -char *long_value; +static char long_key[XATTR_NAME_LEN ]; +static char *long_value; +static char *xattr_value =XATTR_TEST_VALUE ;struct test_case { -char *fname;char *key; -char *value; +char **value;size_t size;int flags;int exp_err; };struct test_case tc[] = { {/* case 00, invalid flags */ - .fname = filename, - .key =XATTR_TEST_KEY , - .value =XATTR_TEST_VALUE , + .key = long_key, + .value = &xattr_value, .size =XATTR_TEST_VALUE_SIZE , .flags = ~0 , .exp_err =EINVAL , }, {/* case 01, replace non-existing attribute */ - .fname = filename, .key =XATTR_TEST_KEY , - .value =XATTR_TEST_VALUE , + .value = &xattr_value, .size =XATTR_TEST_VALUE_SIZE , .flags =XATTR_REPLACE , .exp_err =ENODATA , }, - {/* case 02, long key name, key will be set in setup() */ - .fname = filename, - .key =NULL , - .value =XATTR_TEST_VALUE , + {/* case 02, long key name */ + .key = long_key, + .value = &xattr_value, .size =XATTR_TEST_VALUE_SIZE , .flags =XATTR_CREATE , .exp_err =ERANGE , }, - {/* case 03, long value, value will be set in setup() */ - .fname = filename, + {/* case 03, long value */ .key =XATTR_TEST_KEY , - .value =NULL , + .value = &long_value, .size =XATTR_SIZE_MAX +1 , .flags =XATTR_CREATE , .exp_err =E2BIG , }, {/* case 04, zero length value */ - .fname = filename, .key =XATTR_TEST_KEY , - .value =XATTR_TEST_VALUE , + .value = &xattr_value, .size =0 , .flags =XATTR_CREATE , .exp_err =0 , }, {/* case 05, create existing attribute */ - .fname = filename, .key =XATTR_TEST_KEY , - .value =XATTR_TEST_VALUE , + .value = &xattr_value, .size =XATTR_TEST_VALUE_SIZE , .flags =XATTR_CREATE , .exp_err =EEXIST , }, {/* case 06, replace existing attribute */ - .fname = filename, .key =XATTR_TEST_KEY , - .value =XATTR_TEST_VALUE , + .value = &xattr_value, .size =XATTR_TEST_VALUE_SIZE , .flags =XATTR_REPLACE , .exp_err =0 , - }, + }, }; -int TST_TOTAL =sizeof (tc) /sizeof (tc[0 ]); - -int main (int argc,char *argv[]) +static void verify_setxattr (unsigned int i) { -int lc; -int i; +TEST (setxattr (FNAME , tc[i].key, *tc[i].value, tc[i].size, tc[i].flags)); -tst_parse_opts (argc, argv,NULL ,NULL ); +if (TEST_RETURN ==-1 &&TEST_ERRNO ==EOPNOTSUPP ) +tst_brk (TCONF ,"setxattr() not supported" ); -setup (); +if (!tc[i].exp_err) { +if (TEST_RETURN ) { +tst_res (TFAIL |TTERRNO , +"setxattr() failed with %li" ,TEST_RETURN ); +return ; + } -for (lc =0 ;TEST_LOOPING (lc); lc++) { - tst_count =0 ; +tst_res (TPASS ,"setxattr() passed" ); +return ; + } -for (i =0 ; i <TST_TOTAL ; i++) { -TEST (setxattr (tc[i].fname, tc[i].key, tc[i].value, - tc[i].size, tc[i].flags)); +if (TEST_RETURN ==0 ) { +tst_res (TFAIL ,"setxattr() passed unexpectedly" ); +return ; + } -if (TEST_ERRNO == tc[i].exp_err) { -tst_resm (TPASS |TTERRNO ,"expected behavior" ); - }else { -tst_resm (TFAIL |TTERRNO ,"unexpected behavior " -"- expected errno %d - Got" , - tc[i].exp_err); - } - } +if (TEST_ERRNO != tc[i].exp_err) { +tst_res (TFAIL |TTERRNO ,"setxattr() should fail with %s" , +tst_strerrno (tc[i].exp_err)); +return ; } -cleanup (); -tst_exit (); +tst_res (TPASS |TTERRNO ,"setxattr() failed" ); }static void setup (void ) { -int fd; - -tst_require_root (); +SAFE_TOUCH (FNAME ,0644 ,NULL ); -tst_tmpdir (); - -/* Test for xattr support */ - fd =SAFE_CREAT (cleanup,"testfile" ,0644 ); -close (fd); -if (setxattr ("testfile" ,"user.test" ,"test" ,4 ,XATTR_CREATE ) ==-1 ) -if (errno ==ENOTSUP ) -tst_brkm (TCONF , cleanup,"No xattr support in fs or " -"mount without user_xattr option" ); - -/* Create test file */ -snprintf (filename,BUFSIZ ,"setxattr01testfile" ); - fd =SAFE_CREAT (cleanup, filename,0644 ); -close (fd); - -/* Prepare test cases */ snprintf (long_key,6 ,"%s" ,"user." );memset (long_key +5 ,'k' ,XATTR_NAME_LEN -5 ); long_key[XATTR_NAME_LEN -1 ] ='\0' ; - tc[2 ].key = long_key; - long_value =malloc (XATTR_SIZE_MAX +2 ); -if (!long_value) -tst_brkm (TBROK |TERRNO , cleanup,"malloc failed" ); + long_value =SAFE_MALLOC (XATTR_SIZE_MAX +2 );memset (long_value,'v' ,XATTR_SIZE_MAX +2 ); long_value[XATTR_SIZE_MAX +1 ] ='\0' ; - tc[3 ].value = long_value; - -TEST_PAUSE ; } -static void cleanup (void ) -{ -tst_rmdir (); -} +static struct tst_test test = { + .setup = setup, + .test = verify_setxattr, + .tcnt =ARRAY_SIZE (tc), + .needs_tmpdir =1 , + .needs_root =1 , +}; +#else /* HAVE_SYS_XATTR_H */ -int main (int argc,char *argv[]) -{ -tst_brkm (TCONF ,NULL ,"<sys/xattr.h> does not exist." ); -} +TST_TEST_TCONF ("<sys/xattr.h> does not exist" );#endif
Signature · 1 line
2.13.5
PATCH v3 11/16 syscalls/setxattr01: Run test for all filesystems
In reply to Cyril Hrubis--- testcases/kernel/syscalls/setxattr/setxattr01.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
testcases/kernel/syscalls/setxattr/setxattr01.c +7 -3
@@ -66,7 +66,8 @@#define XATTR_TEST_KEY "user.testkey"#define XATTR_TEST_VALUE "this is a test value"#define XATTR_TEST_VALUE_SIZE 20 -#define FNAME "setxattr01testfile" +#define MNTPOINT "mntpoint" +#define FNAME MNTPOINT"/setxattr01testfile"static char long_key[XATTR_NAME_LEN ];static char *long_value;
@@ -165,8 +166,6 @@ static void verify_setxattr(unsigned int i)static void setup (void ) { -SAFE_TOUCH (FNAME ,0644 ,NULL ); -snprintf (long_key,6 ,"%s" ,"user." );memset (long_key +5 ,'k' ,XATTR_NAME_LEN -5 ); long_key[XATTR_NAME_LEN -1 ] ='\0' ;
@@ -174,12 +173,17 @@ static void setup(void) long_value =SAFE_MALLOC (XATTR_SIZE_MAX +2 );memset (long_value,'v' ,XATTR_SIZE_MAX +2 ); long_value[XATTR_SIZE_MAX +1 ] ='\0' ; + +SAFE_TOUCH (FNAME ,0644 ,NULL ); }static struct tst_test test = { .setup = setup, .test = verify_setxattr, .tcnt =ARRAY_SIZE (tc), + .mntpoint =MNTPOINT , + .mount_device =1 , + .all_filesystems =1 , .needs_tmpdir =1 , .needs_root =1 , };
Signature · 1 line
2.13.5
PATCH v3 12/16 syscallse/setxattr02: Convert to the new library
In reply to Cyril Hrubis--- testcases/kernel/syscalls/setxattr/setxattr02.c | 120 ++++++++---------------- 1 file changed, 41 insertions(+), 79 deletions(-)
testcases/kernel/syscalls/setxattr/setxattr02.c +41 -79
@@ -57,10 +57,7 @@#ifdef HAVE_SYS_XATTR_H # include <sys/xattr.h> #endif -#include "test.h" -#include "safe_macros.h" - -char *TCID ="setxattr02" ; +#include "tst_test.h" #ifdef HAVE_SYS_XATTR_H #define XATTR_TEST_KEY "user.testkey"
@@ -75,9 +72,6 @@ char *TCID = "setxattr02";#define BLK "setxattr02blk"#define SOCK "setxattr02sock" -static void setup (void ); -static void cleanup (void ); -struct test_case {char *fname;char *key;
@@ -145,91 +139,59 @@ static struct test_case tc[] = { }, }; -int TST_TOTAL =sizeof (tc) /sizeof (tc[0 ]); - -int main (int argc,char *argv[]) +static void verify_setxattr (unsigned int i) { -int lc; -int i; +TEST (setxattr (tc[i].fname, tc[i].key, tc[i].value, tc[i].size, tc[i].flags)); -tst_parse_opts (argc, argv,NULL ,NULL ); +if (TEST_RETURN ==-1 &&TEST_ERRNO ==EOPNOTSUPP ) +tst_brk (TCONF ,"setxattr() not supported" ); -setup (); +if (!tc[i].exp_err) { +if (TEST_RETURN ) { +tst_res (TFAIL |TTERRNO , +"setxattr() failed with %li" ,TEST_RETURN ); +return ; + } -for (lc =0 ;TEST_LOOPING (lc); lc++) { - tst_count =0 ; +tst_res (TPASS ,"setxattr() passed" ); +return ; + } -for (i =0 ; i <TST_TOTAL ; i++) { -TEST (setxattr (tc[i].fname, tc[i].key, tc[i].value, - tc[i].size, tc[i].flags)); +if (TEST_RETURN ==0 ) { +tst_res (TFAIL ,"setxattr() passed unexpectedly" ); +return ; + } -if (TEST_ERRNO == tc[i].exp_err) { -tst_resm (TPASS |TTERRNO ,"expected behavior" ); - }else { -tst_resm (TFAIL |TTERRNO ,"unexpected behavior " -"- expected errno %d - Got" , - tc[i].exp_err); - } - } +if (TEST_ERRNO != tc[i].exp_err) { +tst_res (TFAIL |TTERRNO ,"setxattr() should fail with %s" , +tst_strerrno (tc[i].exp_err)); +return ; } -cleanup (); -tst_exit (); +tst_res (TPASS |TTERRNO ,"setxattr() failed" ); }static void setup (void ) { -int fd; -dev_t dev; - -tst_require_root (); - -tst_tmpdir (); - -/* Test for xattr support */ - fd =SAFE_CREAT (cleanup,"testfile" ,0644 ); -close (fd); -if (setxattr ("testfile" ,"user.test" ,"test" ,4 ,XATTR_CREATE ) ==-1 ) -if (errno ==ENOTSUP ) -tst_brkm (TCONF , cleanup,"No xattr support in fs or " -"mount without user_xattr option" ); -unlink ("testfile" ); - -/* Create test files */ - fd =SAFE_CREAT (cleanup,FILENAME ,0644 ); -close (fd); - -SAFE_MKDIR (cleanup,DIRNAME ,0644 ); - -SAFE_SYMLINK (cleanup,FILENAME ,SYMLINK ); - -if (mknod (FIFO ,S_IFIFO |0777 ,0 ) ==-1 ) -tst_brkm (TBROK |TERRNO , cleanup,"Create FIFO(%s) failed" , -FIFO ); - - dev =makedev (1 ,3 ); -if (mknod (CHR ,S_IFCHR |0777 , dev) ==-1 ) -tst_brkm (TBROK |TERRNO , cleanup,"Create char special(%s)" -" failed" ,CHR ); - -if (mknod (BLK ,S_IFBLK |0777 ,0 ) ==-1 ) -tst_brkm (TBROK |TERRNO , cleanup,"Create block special(%s)" -" failed" ,BLK ); - -if (mknod (SOCK ,S_IFSOCK |0777 ,0 ) ==-1 ) -tst_brkm (TBROK |TERRNO , cleanup,"Create socket(%s) failed" , -SOCK ); - -TEST_PAUSE ; +dev_t dev =makedev (1 ,3 ); + +SAFE_TOUCH (FILENAME ,0644 ,NULL ); +SAFE_MKDIR (DIRNAME ,0644 ); +SAFE_SYMLINK (FILENAME ,SYMLINK ); +SAFE_MKNOD (FIFO ,S_IFIFO |0777 ,0 ); +SAFE_MKNOD (CHR ,S_IFCHR |0777 , dev); +SAFE_MKNOD (BLK ,S_IFBLK |0777 ,0 ); +SAFE_MKNOD (SOCK ,S_IFSOCK |0777 ,0 ); } -static void cleanup (void ) -{ -tst_rmdir (); -} +static struct tst_test test = { + .setup = setup, + .test = verify_setxattr, + .tcnt =ARRAY_SIZE (tc), + .needs_tmpdir =1 , + .needs_root =1 , +}; +#else /* HAVE_SYS_XATTR_H */ -int main (int argc,char *argv[]) -{ -tst_brkm (TCONF ,NULL ,"<sys/xattr.h> does not exist." ); -} +TST_TEST_TCONF ("<sys/xattr.h> does not exist" );#endif
Signature · 1 line
2.13.5
PATCH v3 13/16 syscalls/fsync01: Convert to the new library.
In reply to Cyril Hrubis--- testcases/kernel/syscalls/fsync/fsync01.c | 157 +++++------------------------- 1 file changed, 27 insertions(+), 130 deletions(-)
testcases/kernel/syscalls/fsync/fsync01.c +27 -130
@@ -1,5 +1,7 @@/* * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +* AUTHOR : William Roske +* CO-PILOT : Dave Fenner * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as
@@ -30,149 +32,44 @@* http://oss.sgi.com/projects/GenInfo/NoticeExplan/ * */ -/* $Id: fsync01.c,v 1.6 2009/10/26 14:55:47 subrata_modak Exp $ */ -/********************************************************** -* -* OS Test - Silicon Graphics, Inc. -* -* TEST IDENTIFIER : fsync01 -* -* EXECUTED BY : anyone -* -* TEST TITLE : Basic test for fsync(2) -* -* PARENT DOCUMENT : usctpl01 -* -* TEST CASE TOTAL : 1 -* -* WALL CLOCK TIME : 1 -* -* CPU TYPES : ALL -* -* AUTHOR : William Roske -* -* CO-PILOT : Dave Fenner -* -* DATE STARTED : 03/30/92 -* -* INITIAL RELEASE : UNICOS 7.0 -* -* TEST CASES -* -* 1.) fsync(2) returns...(See Description) -* -* INPUT SPECIFICATIONS -* The standard options for system call tests are accepted. -* (See the parse_opts(3) man page). -* -* OUTPUT SPECIFICATIONS -*$ -* DURATION -* Terminates - with frequency and infinite modes. -* -* SIGNALS -* Uses SIGUSR1 to pause before test if option set. -* (See the parse_opts(3) man page). -* -* RESOURCES -* None -* -* ENVIRONMENTAL NEEDS -* No run-time environmental needs. -* -* SPECIAL PROCEDURAL REQUIREMENTS -* None -* -* INTERCASE DEPENDENCIES -* None -* -* DETAILED DESCRIPTION -* This is a Phase I test for the fsync(2) system call. It is intended -* to provide a limited exposure of the system call, for now. It -* should/will be extended when full functional tests are written for -* fsync(2). -* -* Setup: -* Setup signal handling. -* Pause for SIGUSR1 if option specified. -* -* Test: -* Loop if the proper options are given. -* Execute system call -* Check return code, if system call failed (return=-1) -* Log the errno and Issue a FAIL message. -* Otherwise, Issue a PASS message. -* -* Cleanup: -* Print errno log and/or timing stats if options given -* -* -*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/ -#include <sys/types.h> -#include <fcntl.h> -#include <sys/statfs.h> +#include <unistd.h> #include <errno.h> -#include <string.h> -#include <signal.h> -#include "test.h" - -void setup (); -void cleanup (); +#include <stdio.h> -char *TCID ="fsync01" ; -int TST_TOTAL =1 ; +#include "tst_test.h" -char fname[255 ]; -int fd; -char *buf ="davef" ; +static char fname[255 ]; +static int fd; +#define BUF "davef" -int main (int ac,char **av) +static void verify_fsync (void ) { -int lc; - -tst_parse_opts (ac, av,NULL ,NULL ); - -setup (); +SAFE_WRITE (1 , fd,BUF ,sizeof (BUF )); -for (lc =0 ;TEST_LOOPING (lc); lc++) { +TEST (fsync (fd)); - tst_count =0 ; - -if (write (fd, buf,strlen (buf)) ==-1 ) -tst_brkm (TBROK |TERRNO , cleanup,"write failed" ); -TEST (fsync (fd)); - -if (TEST_RETURN ==-1 ) -tst_resm (TFAIL |TTERRNO ,"fsync failed" ); -else -tst_resm (TPASS ,"fsync returned %ld" ,TEST_RETURN ); - - } - -cleanup (); -tst_exit (); +if (TEST_RETURN ==-1 ) +tst_res (TFAIL |TTERRNO ,"fsync failed" ); +else +tst_res (TPASS ,"fsync() returned %ld" ,TEST_RETURN ); } -void setup (void ) +static void setup (void ) { - -tst_sig (NOFORK ,DEF_HANDLER , cleanup); - -TEST_PAUSE ; - -tst_tmpdir (); -sprintf (fname,"tfile_%d" ,getpid ()); -if ((fd =open (fname,O_RDWR |O_CREAT ,0700 )) ==-1 ) -tst_brkm (TBROK |TERRNO , cleanup,"open failed" ); + fd =SAFE_OPEN (fname,O_RDWR |O_CREAT ,0700 ); } -void cleanup (void ) +static void cleanup (void ) { -if (close (fd) ==-1 ) -tst_resm (TWARN ,"close failed" ); - -tst_rmdir (); - +if (fd >0 ) +SAFE_CLOSE (fd); } + +static struct tst_test test = { + .cleanup = cleanup, + .setup = setup, + .test_all = verify_fsync, + .needs_tmpdir =1 , +};
Signature · 1 line
2.13.5
PATCH v3 14/16 syscalls/fsync01: Run test for all filesystems.
In reply to Cyril Hrubis+ do write() + fsync() 10 times
--- testcases/kernel/syscalls/fsync/fsync01.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
testcases/kernel/syscalls/fsync/fsync01.c +15 -7
@@ -45,19 +45,23 @@ static int fd;static void verify_fsync (void ) { -SAFE_WRITE (1 , fd,BUF ,sizeof (BUF )); +unsigned int i; -TEST (fsync (fd)); +for (i =0 ; i <10 ; i++) { +SAFE_WRITE (1 , fd,BUF ,sizeof (BUF )); -if (TEST_RETURN ==-1 ) -tst_res (TFAIL |TTERRNO ,"fsync failed" ); -else -tst_res (TPASS ,"fsync() returned %ld" ,TEST_RETURN ); +TEST (fsync (fd)); + +if (TEST_RETURN ==-1 ) +tst_res (TFAIL |TTERRNO ,"fsync failed" ); +else +tst_res (TPASS ,"fsync() returned %ld" ,TEST_RETURN ); + } }static void setup (void ) { -sprintf (fname,"tfile_%d" ,getpid ()); +sprintf (fname,"mntpoint/tfile_%d" ,getpid ()); fd =SAFE_OPEN (fname,O_RDWR |O_CREAT ,0700 ); }
@@ -72,4 +76,8 @@ static struct tst_test test = { .setup = setup, .test_all = verify_fsync, .needs_tmpdir = 1, + .needs_root = 1, + .mount_device = 1, + .mntpoint = "mntpoint", + .all_filesystems = 1, };
Signature · 1 line
2.13.5
PATCH v3 15/16 fs/fs_fill: Add a test to fill a FS in a few threads
In reply to Cyril HrubisRuns CPU+2 threads that write into FS until they got ENOSPC, then delete a file and continue.
Older exfat fails with EIO instead of ENOSPC, it has been fixed in:
commit ca112f07b115a419250b6526e71345dcd29e4d67
Author: relan <[email protected]> Date: Tue Dec 27 17:22:12 2016 +0300
Propagate ENOSPC on write.
at:
https://github.com/relan/exfat/
--- runtest/fs | 2 + testcases/kernel/fs/fs_fill/.gitignore | 1 + testcases/kernel/fs/fs_fill/Makefile | 22 ++++++ testcases/kernel/fs/fs_fill/fs_fill.c | 122 +++++++++++++++++++++++++++++++++ 4 files changed, 147 insertions(+) create mode 100644 testcases/kernel/fs/fs_fill/.gitignore create mode 100644 testcases/kernel/fs/fs_fill/Makefile create mode 100644 testcases/kernel/fs/fs_fill/fs_fill.c
runtest/fs +2 -0
@@ -76,3 +76,5 @@ fs_racer fs_racer.sh -t 5 quota_remount_test01 quota_remount_test01.sh isofs isofs.sh + +fs_fill fs_fill
testcases/kernel/fs/fs_fill/.gitignore new file +1 -0
@@ -0,0 +1 @@ +fs_fill
testcases/kernel/fs/fs_fill/Makefile new file +22 -0
@@ -0,0 +1,22 @@ +# Copyright (c) 2017 Linux Test Project +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +top_srcdir ?= ../../../.. + +include $(top_srcdir)/include/mk/testcases.mk + +CFLAGS += -pthread + +include $(top_srcdir)/include/mk/generic_leaf_target.mk
testcases/kernel/fs/fs_fill/fs_fill.c new file +122 -0
122 lines not on this page · raw message
Signature · 1 line
2.13.5
PATCH v3 15/16 fs/fs_fill: Add a test to fill a FS in a few threads
Hi Cyril,
This case always broken in SAFE_* operations, seems the reason is no space left on the device,
so I wonder if is it necessary to create so many thread "CPUs + 2" to run the test?
What about just creating half of CPU number thread (nthreads = tst_ncpus_conf()/2 + 1) there?
$ git diff
(quoted diff) +0 -0
b/testcases/kernel/fs/fs_fill/fs_fill.c
index a50a22f..13207c4 100644
testcases/kernel/fs/fs_fill/fs_fill.c +1 -1
@@ -106,7 +106,7 @@ static void testrun(void)static void setup (void ) { - nthreads =tst_ncpus_conf () +2 ; + nthreads =tst_ncpus_conf ()/2 +1 ;tst_res (TINFO ,"Running %i writer threads" , nthreads); }
Broken message:
==============
fs_fill.c:104: PASS: Got 73 ENOSPC runtime 1000ms tst_mkfs.c:83: INFO: Formatting /dev/loop1 with xfs opts='' extra opts='' tst_test.c:970: INFO: Timeout per run is 0h 05m 00s fs_fill.c:111: INFO: Running 66 writer threads safe_macros.c:225: BROK: tst_fill_fs.c:43:open(mntpoint/thread48/file0,65,0700) failed: ENOSPC
Signature · 2 lines
Li Wang [email protected]
PATCH v3 15/16 fs/fs_fill: Add a test to fill a FS in a few threads
Hi!
Quoted 15 lines
This case always broken in SAFE_* operations, seems the reason is no space left on the device,
so I wonder if is it necessary to create so many thread "CPUs + 2" to run the test?What about just creating half of CPU number thread (nthreads = tst_ncpus_conf()/2 + 1) there?
$ git difftestcases/kernel/fs/fs_fill/fs_fill.c +0
-0
testcases/kernel/fs/fs_fill/fs_fill.c static void testrun(void) · line 112
Quoted 8 lines
testcases/kernel/fs/fs_fill/fs_fill.c +1
-1@@ -106,7 +106,7 @@ static void testrun(void)static void setup (void ) { - nthreads =tst_ncpus_conf () +2 ; + nthreads =tst_ncpus_conf ()/2 +1 ;tst_res (TINFO ,"Running %i writer threads" , nthreads); }
This does not fix the problem, only makes it less likely.
The correct fix is to use open() instead of SAFE_OPEN() in the tst_fill_fs() and just return from the function when we get ENOSPC. I can fix that, or you can send the patch. Either way thanks for pointing out the mistake.
Signature · 2 lines
Cyril Hrubis [email protected]
PATCH v3 15/16 fs/fs_fill: Add a test to fill a FS in a few threads
Quoted 22 lines · Cyril Hrubis
Hi!
Quoted 21 lines
This case always broken in SAFE_* operations, seems the reason is no space left on the device,
so I wonder if is it necessary to create so many thread "CPUs + 2" to run the test?What about just creating half of CPU number thread (nthreads = tst_ncpus_conf()/2 + 1) there?
$ git difftestcases/kernel/fs/fs_fill/fs_fill.c +1
-1@@ -106,7 +106,7 @@ static void testrun(void)static void setup (void ) { - nthreads =tst_ncpus_conf () +2 ; + nthreads =tst_ncpus_conf ()/2 +1 ;
Quoted 4 lines
testcases/kernel/fs/fs_fill/fs_fill.c static void testrun(void) · line 112
Quoted 2 lines
testcases/kernel/fs/fs_fill/fs_fill.c +0
-0tst_res (TINFO ,"Running %i writer threads" , nthreads); }This does not fix the problem, only makes it less likely.
Actually yes. Retest and failed again.
Quoted 5 lines
The correct fix is to use
open()instead ofSAFE_OPEN()in thetst_fill_fs()and just return from the function when we get ENOSPC. I can fix that, or you can send the patch. Either way thanks for pointing out the mistake.
The broken are not only in tst_fills_fs() function but also come from SAFE_MKDIR(w->dir, 0700),SAFE_OPENDIR(w->dir) and SAFE_UNLINK(file).
safe_macros.c:169: BROK: fs_fill.c:49:mkdir(mntpoint/thread21,0700) failed: ENOSPC
If we just handle the 'ENOSPC' in tst_fill_fs(), I doubt that test will be broken as well.
Signature · 2 lines
Li Wang [email protected]
PATCH v3 15/16 fs/fs_fill: Add a test to fill a FS in a few threads
Hi!
Quoted 7 lines
Quoted 4 lines
The correct fix is to use
open()instead ofSAFE_OPEN()in thetst_fill_fs()and just return from the function when we get ENOSPC. I can fix that, or you can send the patch. Either way thanks for pointing out the mistake.The broken are not only in
tst_fills_fs()function but also come fromSAFE_MKDIR(w->dir, 0700),
Ok, we have to create the directories in the testrun() function before we attempt to run the threads, that should fix this particular problem.
Quoted 1 line
SAFE_OPENDIR(w->dir)andSAFE_UNLINK(file).
The opendir() should not fail with ENOSPC since that only reads the directory content.
And the unlink() should not fail with ENOSPC as well. Since unlink() actually deletes a file, if that breaks because filesystem is full you lost since you cannot free any space by removing files...
So fixing the tst_fill_fs() and doing the mkdir() before we start these threads should IMHO fix the test.
Signature · 2 lines
Cyril Hrubis [email protected]
PATCH v3 15/16 fs/fs_fill: Add a test to fill a FS in a few threads
Quoted 17 lines · Cyril Hrubis
Hi!
Quoted 7 lines
Quoted 4 lines
The correct fix is to use
open()instead ofSAFE_OPEN()in thetst_fill_fs()and just return from the function when we get ENOSPC. I can fix that, or you can send the patch. Either way thanks for pointing out the mistake.The broken are not only in
tst_fills_fs()function but also come fromSAFE_MKDIR(w->dir, 0700),Ok, we have to create the directories in the
testrun()function before we attempt to run the threads, that should fix this particular problem.Quoted 1 line
SAFE_OPENDIR(w->dir)andSAFE_UNLINK(file).The
opendir()should not fail with ENOSPC since that only reads the directory content.
Quoted 6 lines
And the
unlink()should not fail with ENOSPC as well. Sinceunlink()actually deletes a file, if that breaks because filesystem is full you lost since you cannot free any space by removing files...So fixing the
tst_fill_fs()and doing themkdir()before we start these threads should IMHO fix the test.
OK, Thanks for your analysis. Let me try to fix the mistake and test on my system.
Will send a new patch if I can confirm the issue being fully fixed like this.
Signature · 2 lines
Li Wang [email protected]
PATCH v3 16/16 doc: Update device flags in test-writing-guidelines
In reply to Cyril Hrubis--- doc/test-writing-guidelines.txt | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
doc/test-writing-guidelines.txt +17 -2
@@ -914,12 +914,27 @@ then. If '.format_device' flag is set the device is formatted with a filesystem as well. You can use '.dev_fs_type' to override the default filesystem type if needed and pass additional options to mkfs via '.dev_fs_opts' and -'.dev_extra_opt' pointers. +'.dev_extra_opt' pointers. Note that '.format_device' implies '.needs_device' +there is no need to set both. If '.mount_device' is set, the device is mounted at '.mntpoint' which is used to pass a directory name that will be created and used as mount destination. You can pass additional flags and data to the mount command via '.mnt_flags' -and '.mnt_data' pointers. +and '.mnt_data' pointers. Note that '.mount_device' implies '.needs_device' +and '.format_device' so there is no need to set the later two. + +If '.needs_rofs' is set, read-only filesystem is mounted at '.mntpoint' this +one is supposed to be used for 'EROFS' tests. + +If '.all_filesystems' is set the test function is executed for all supported +filesystems. Supported filesystems are detected based on existence of the +'mkfs.$fs' helper and on kernel support to mount it. For each supported +filesystem the 'tst_device.fs_type' is set to the currently tested fs type, if +'.format_device' is set the device is formatted as well, if '.mount_device' is +set it's mounted at '.mntpoint'. Also the test timeout is reset for each +execution of the test fuction. This flag is expected to be used for filesystem +related syscalls that are at least partly implemented in the filesystem +specific code e.g. fallocate(). [source,c] -------------------------------------------------------------------------------
Signature · 1 line
2.13.5
PATCH v3 16/16 doc: Update device flags in test-writing-guidelines
Quoted 16 lines · Cyril Hrubis
Signed-off-by Cyril Hrubis <[email protected]>--- doc/test-writing-guidelines.txt | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)doc/test-writing-guidelines.txt +2
-1@@ -914,12 +914,27 @@ then. If '.format_device' flag is set the device is formatted with a filesystem as well. You can use '.dev_fs_type' to override the default filesystem type if needed and pass additional options to mkfs via '.dev_fs_opts' and -'.dev_extra_opt' pointers. +'.dev_extra_opt' pointers. Note that '.format_device' implies '.needs_device' +there is no need to set both.
doc/test-writing-guidelines.txt then. · line 927
Quoted 10 lines
doc/test-writing-guidelines.txt +5
-1If '.mount_device' is set, the device is mounted at '.mntpoint' which is used to pass a directory name that will be created and used as mount destination. You can pass additional flags and data to the mount command via '.mnt_flags' -and '.mnt_data' pointers. +and '.mnt_data' pointers. Note that '.mount_device' implies '.needs_device' +and '.format_device' so there is no need to set the later two. + +If '.needs_rofs' is set, read-only filesystem is mounted at '.mntpoint' this +one is supposed to be used for 'EROFS' tests.
I probably should have done this with the patches. :(
<snip>