syscalls: new test writev07
PATCH v2 1/3 syscalls: new test writev07
Verify writev() behaviour with partially valid iovec list. Kernel <4.8 used to shorten write up to first bad invalid iovec. Starting with 4.8, a writev with short data (under page size) is likely to get shorten to 0 bytes and return EFAULT.
This test doesn't make assumptions how much will write get shortened. It only tests that file content/offset after syscall corresponds to return value of writev().
See: [RFC] writev() semantics with invalid iovec in the middle
https://marc.info/?l=linux-kernel&m=147388891614289&w=2
This test is meant to be replacement for writev03/writev04 and part of writev01, which all deal with partially invalid iovec lists, and all currently fail with 4.8 kernel.
---
Changes in v2:
- use tst_res_hexd
- smaller iovec with less random offsets and sizes
- fix tid
runtest/ltplite | 1 + runtest/stress.part3 | 1 + runtest/syscalls | 1 + testcases/kernel/syscalls/.gitignore | 1 + testcases/kernel/syscalls/writev/writev07.c | 152 ++++++++++++++++++++++++++++ 5 files changed, 156 insertions(+) create mode 100644 testcases/kernel/syscalls/writev/writev07.c
runtest/ltplite +1 -0
@@ -1047,6 +1047,7 @@ writev03 writev03 writev04 writev04 writev05 writev05 writev06 writev06 +writev07 writev07 #DESCRIPTION:Memory Mgmt tests mm01 mmap001 -m 10000
runtest/stress.part3 +1 -0
@@ -908,6 +908,7 @@ writev03 writev03 writev04 writev04 writev05 writev05 writev06 writev06 +writev07 writev07 pty01 pty01 hangup01 hangup01
runtest/syscalls +1 -0
@@ -1426,6 +1426,7 @@ writev03 writev03 writev04 writev04 writev05 writev05 writev06 writev06 +writev07 writev07 perf_event_open01 perf_event_open01 perf_event_open02 perf_event_open02
testcases/kernel/syscalls/.gitignore +1 -0
@@ -1104,6 +1104,7 @@ /writev/writev04 /writev/writev05 /writev/writev06 +/writev/writev07 /fanotify/fanotify01 /fanotify/fanotify02 /fanotify/fanotify03
testcases/kernel/syscalls/writev/writev07.c new file +152 -0
152 lines not on this page · raw message
Signature · 1 line
1.8.3.1
PATCH v2 2/3 writev: remove writev03 and writev04
Removed tests are almost identical, and there is now a new
test: writev07, which is meant to be a replacement.
--- doc/testcases/kernel.txt | 23 -- runtest/ltplite | 2 - runtest/stress.part3 | 2 - runtest/syscalls | 2 - testcases/kernel/syscalls/.gitignore | 2 - testcases/kernel/syscalls/writev/Makefile | 2 +- testcases/kernel/syscalls/writev/writev03.c | 271 --------------------- testcases/kernel/syscalls/writev/writev04.c | 353 ---------------------------- 8 files changed, 1 insertion(+), 656 deletions(-) delete mode 100644 testcases/kernel/syscalls/writev/writev03.c delete mode 100644 testcases/kernel/syscalls/writev/writev04.c
doc/testcases/kernel.txt +0 -23
@@ -6897,29 +6897,6 @@ ltp/testcases/kernel/syscalls/writev/writev02.c <\test_location> <\testname> -<testname=writev03> - <description> - The testcases are written calling writev() with partially valid data - to overwrite the contents, to write in the beginning and to write in - the end of the file. - - <\description> - <test_location> - ltp/testcases/kernel/syscalls/writev/writev03.c - <\test_location> -<\testname> -<testname=writev04> - <description> - The testcases are written calling writev() with partially valid data - to overwrite the contents, to write in the beginning and to write in - the end of the file. This is same as writev03, but the length of - buffer used here is 8192 bytes. - - <\description> - <test_location> - ltp/testcases/kernel/syscalls/writev/writev04.c - <\test_location> -<\testname> <testname=writev05> <description> These testcases are written to test writev() on sparse files. This
runtest/ltplite +0 -2
@@ -1043,8 +1043,6 @@ write05 write05 writev01 writev01 writev02 writev02 -writev03 writev03 -writev04 writev04 writev05 writev05 writev06 writev06 writev07 writev07
runtest/stress.part3 +0 -2
@@ -904,8 +904,6 @@ write05 write05 writev01 writev01 writev02 writev02 -writev03 writev03 -writev04 writev04 writev05 writev05 writev06 writev06 writev07 writev07
runtest/syscalls +0 -2
@@ -1422,8 +1422,6 @@ write05 write05 writev01 writev01 writev02 writev02 -writev03 writev03 -writev04 writev04 writev05 writev05 writev06 writev06 writev07 writev07
testcases/kernel/syscalls/.gitignore +0 -2
@@ -1100,8 +1100,6 @@ /write/write05 /writev/writev01 /writev/writev02 -/writev/writev03 -/writev/writev04 /writev/writev05 /writev/writev06 /writev/writev07
testcases/kernel/syscalls/writev/Makefile +1 -1
@@ -19,7 +19,7 @@ top_srcdir ?= ../../../.. ifeq ($(UCLINUX),1) -FILTER_OUT_MAKE_TARGETS += writev02 writev03 +FILTER_OUT_MAKE_TARGETS += writev02 endif include $(top_srcdir)/include/mk/testcases.mk
testcases/kernel/syscalls/writev/writev03.c deleted +0 -271
271 lines not on this page · raw message
testcases/kernel/syscalls/writev/writev04.c deleted +0 -353
353 lines not on this page · raw message
Signature · 1 line
1.8.3.1
PATCH v2 3/3 writev01: rewrite and drop partially valid iovec tests
In reply to Jan StancekConvert to newlib style, and drop tests for partially valid iovec lists, these are now tested in writev07.
--- testcases/kernel/syscalls/writev/writev01.c | 550 ++++++++-------------------- 1 file changed, 152 insertions(+), 398 deletions(-)
rewrite testcases/kernel/syscalls/writev/writev01.c (90%)
testcases/kernel/syscalls/writev/writev01.c +152 -398
@@ -1,398 +1,152 @@ -/* -* -* Copyright (c) International Business Machines Corp., 2001 -* -* 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, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* -* NAME -* writev01.c -* -* DESCRIPTION -* Testcase to check the basic functionality of writev(2) system call. -* -* ALGORITHM -* Create a IO vector, and attempt to writev various components of it. -* -* USAGE: <for command-line> -* writev01 [-c n] [-e] [-i n] [-I x] [-P x] [-t] -* where, -c n : Run n copies concurrently. -* -e : Turn on errno logging. -* -i n : Execute test n times. -* -I x : Execute test for x seconds. -* -P x : Pause for x seconds between iterations. -* -t : Turn on syscall timing. -* -* History -* 07/2001 John George -* -Ported -* 04/2002 wjhuie sigset cleanups -* 06/2002 Shaobo Li -* fix testcase 7, add each testcase comment. -* -* Restrictions -* None -*/ - -#include <stdio.h> -#include <sys/types.h> -#include <signal.h> -#include <sys/uio.h> -#include <sys/fcntl.h> -#include <memory.h> -#include <errno.h> -#include "test.h" -#include <sys/mman.h> - -#define K_1 1024 -#define M_1 K_1 * K_1 -#define G_1 M_1 * K_1 - -#define NBUFS 4 -#define CHUNK 64/* single chunk */ -#define MAX_IOVEC 16 -#define DATA_FILE "writev_data_file" - -char buf1[K_1 ], buf2[K_1 ], buf3[K_1 ]; - -struct iovec wr_iovec[MAX_IOVEC ] = { -/* iov_base *//* iov_len */ - -/* testcase# 1 */ - {buf1,-1 }, - {(buf1 +CHUNK ),CHUNK }, - {(buf1 +CHUNK *2 ),CHUNK }, - -/* testcase# 2 */ - {(buf1 +CHUNK *3 ),G_1 }, - {(buf1 +CHUNK *4 ),G_1 }, - {(buf1 +CHUNK *5 ),G_1 }, - -/* testcase# 3 */ - {(buf1 +CHUNK *6 ),CHUNK }, - {(caddr_t) -1 ,CHUNK }, - {(buf1 +CHUNK *8 ),CHUNK }, - -/* testcase# 4 */ - {(buf1 +CHUNK *9 ),CHUNK }, - -/* testcase# 5 */ - {(buf1 +CHUNK *10 ),CHUNK }, - -/* testcase# 6 */ - {(buf1 +CHUNK *11 ),CHUNK }, - -/* testcase# 7 */ - {(buf1 +CHUNK *12 ),CHUNK }, - -/* testcase# 8 */ - {(buf1 +CHUNK *13 ),0 }, - -/* testcase# 7 */ - {NULL ,0 }, - {NULL ,0 } -}; - -char name[K_1 ], f_name[K_1 ]; - -char *bad_addr =0 ; - -int fd[4 ], in_sighandler; -int pfd[2 ];/* pipe fd's */ -char *buf_list[NBUFS ]; - -void sighandler (int ); -int fill_mem (char *,int ,int ); -void init_buffs (char *[]); -void setup (void ); -void cleanup (void ); - -char *TCID ="writev01" ; -int TST_TOTAL =1 ; - -int main (int argc,char **argv) -{ -int nbytes, ret; - -int lc; - -tst_parse_opts (argc, argv,NULL ,NULL ); - -setup (); - -for (lc =0 ;TEST_LOOPING (lc); lc++) { - - tst_count =0 ; - - buf_list[0 ] = buf1; - buf_list[1 ] = buf2; - buf_list[2 ] = buf3; - buf_list[3 ] =NULL ; - - fd[1 ] =-1 ;/* Invalid file descriptor */ - -if (signal (SIGTERM , sighandler) ==SIG_ERR ) -tst_brkm (TBROK |TERRNO , cleanup, -"signal(SIGTERM, ..) failed" ); - -if (signal (SIGPIPE , sighandler) ==SIG_ERR ) -tst_brkm (TBROK |TERRNO , cleanup, -"signal(SIGPIPE, ..) failed" ); - -init_buffs (buf_list); - -if ((fd[0 ] =open (f_name,O_WRONLY |O_CREAT ,0666 )) ==-1 ) -tst_brkm (TBROK |TERRNO , cleanup, -"open(.., O_WRONLY|O_CREAT, ..) failed" ); -else if ((nbytes =write (fd[0 ], buf_list[2 ],K_1 )) !=K_1 ) -tst_brkm (TBROK |TERRNO , cleanup,"write failed" ); - -if (close (fd[0 ]) ==-1 ) -tst_brkm (TBROK |TERRNO , cleanup,"close failed" ); - -if ((fd[0 ] =open (f_name,O_RDWR ,0666 )) ==-1 ) -tst_brkm (TBROK |TERRNO , cleanup,"open failed" ); -//block1: /* given vector length -1, writev return EINVAL. */ -tst_resm (TPASS ,"Enter Block 1" ); - -TEST (writev (fd[0 ], wr_iovec,1 )); -if (TEST_RETURN ==-1 ) { -if (TEST_ERRNO ==EINVAL ) -tst_resm (TPASS ,"Received EINVAL as expected" ); -else -tst_resm (TFAIL ,"Expected errno = EINVAL, " -"got %d" ,TEST_ERRNO ); - }else -tst_resm (TFAIL ,"writev failed to fail" ); -tst_resm (TINFO ,"Exit block 1" ); - -//block2: -/* This testcases doesn't look like what it intent to do -* 1. it is not using the wr_iovec initialized -* 2. read() and following message is not consistent -*/ -tst_resm (TPASS ,"Enter block 2" ); - -if (lseek (fd[0 ],CHUNK *6 ,0 ) ==-1 ) -tst_resm (TBROK |TERRNO ,"block2: 1st lseek failed" ); - -if ((ret =writev (fd[0 ], (wr_iovec +6 ),3 )) ==CHUNK ) { -if (lseek (fd[0 ],CHUNK *6 ,0 ) ==-1 ) -tst_brkm (TBROK |TERRNO , cleanup, -"block2: 2nd lseek failed" ); -if ((nbytes =read (fd[0 ], buf_list[0 ],CHUNK )) !=CHUNK ) -tst_resm (TFAIL ,"read failed; expected nbytes " -"= 1024, got = %d" , nbytes); -else if (memcmp ((buf_list[0 ] +CHUNK *6 ), - (buf_list[2 ] +CHUNK *6 ),CHUNK ) !=0 ) -tst_resm (TFAIL ,"writev over " -"wrote %s" , f_name); - }else -tst_resm (TFAIL |TERRNO ,"writev failed unexpectedly" ); -tst_resm (TINFO ,"Exit block 2" ); - -//block3: /* given 1 bad vector buffer with good ones, writev success */ -tst_resm (TPASS ,"Enter block 3" ); - -if (lseek (fd[0 ],CHUNK *6 ,0 ) ==-1 ) -tst_brkm (TBROK |TERRNO , cleanup, -"block3: 1st lseek failed" ); -if ((nbytes =writev (fd[0 ], (wr_iovec +6 ),3 )) ==-1 ) { -if (errno ==EFAULT ) -tst_resm (TFAIL ,"Got EFAULT" ); - } -if (lseek (fd[0 ],0 ,0 ) ==-1 ) -tst_brkm (TBROK , cleanup,"block3: 2nd lseek failed" ); -if ((nbytes =read (fd[0 ], buf_list[0 ],K_1 )) !=K_1 ) { -tst_resm (TFAIL |TERRNO , -"read failed; expected nbytes = 1024, got = %d" , - nbytes); - }else if (memcmp ((buf_list[0 ] +CHUNK *6 ), - (buf_list[2 ] +CHUNK *6 ),CHUNK *3 ) !=0 ) -tst_resm (TFAIL ,"writev overwrote file" ); - -tst_resm (TINFO ,"Exit block 3" ); - -//block4: /* given bad file descriptor, writev return EBADF. */ -tst_resm (TPASS ,"Enter block 4" ); - -TEST (writev (fd[1 ], (wr_iovec +9 ),1 )); -if (TEST_RETURN ==-1 ) { -if (TEST_ERRNO ==EBADF ) -tst_resm (TPASS ,"Received EBADF as expected" ); -else -tst_resm (TFAIL ,"expected errno = EBADF, " -"got %d" ,TEST_ERRNO ); - }else -tst_resm (TFAIL ,"writev returned a " "positive value" ); - -tst_resm (TINFO ,"Exit block 4" ); - -//block5: /* given invalid vector count, writev return EINVAL */ -tst_resm (TPASS ,"Enter block 5" ); - -TEST (writev (fd[0 ], (wr_iovec +10 ),-1 )); -if (TEST_RETURN ==-1 ) { -if (TEST_ERRNO ==EINVAL ) -tst_resm (TPASS ,"Received EINVAL as expected" ); -else -tst_resm (TFAIL ,"expected errno = EINVAL, " -"got %d" ,TEST_ERRNO ); - }else -tst_resm (TFAIL ,"writev returned a " "positive value" ); - -tst_resm (TINFO ,"Exit block 5" ); - -//block6: /* given no buffer vector, writev success */ -tst_resm (TPASS ,"Enter block 6" ); - -TEST (writev (fd[0 ], (wr_iovec +11 ),0 )); -if (TEST_RETURN ==-1 ) -tst_resm (TFAIL |TTERRNO ,"writev failed" ); -else -tst_resm (TPASS ,"writev wrote 0 iovectors" ); - -tst_resm (TINFO ,"Exit block 6" ); - -//block7: -/* given 4 vectors, 2 are NULL, 1 with 0 length and 1 with fixed length, -* writev success writing fixed length. -*/ -tst_resm (TPASS ,"Enter block 7" ); - -if (lseek (fd[0 ],CHUNK *12 ,0 ) ==-1 ) -tst_resm (TBROK ,"lseek failed" ); -else if ((ret =writev (fd[0 ], (wr_iovec +12 ),4 )) !=CHUNK ) -tst_resm (TFAIL ,"writev failed writing %d bytes, " -"followed by two NULL vectors" ,CHUNK ); -else -tst_resm (TPASS ,"writev passed writing %d bytes, " -"followed by two NULL vectors" ,CHUNK ); - -tst_resm (TINFO ,"Exit block 7" ); - -//block8: /* try to write to a closed pipe, writev return EPIPE. */ -tst_resm (TPASS ,"Enter block 8" ); - -if (pipe (pfd) ==-1 ) -tst_resm (TFAIL |TERRNO ,"pipe failed" ); -else { -if (close (pfd[0 ]) ==-1 ) -tst_resm (TFAIL |TERRNO ,"close failed" ); -else if (writev (pfd[1 ], (wr_iovec +12 ),1 ) ==-1 && - in_sighandler) { -if (errno ==EPIPE ) -tst_resm (TPASS ,"Received EPIPE as " -"expected" ); -else -tst_resm (TFAIL |TERRNO , -"didn't get EPIPE" ); - }else -tst_resm (TFAIL ,"writev returned a positive " -"value" ); - } -tst_resm (TINFO ,"Exit block 8" ); - } -cleanup (); -tst_exit (); -} - -void setup (void ) -{ - -tst_sig (FORK , sighandler, cleanup); - -TEST_PAUSE ; - -tst_tmpdir (); - -strcpy (name,DATA_FILE ); -sprintf (f_name,"%s.%d" , name,getpid ()); - - bad_addr =mmap (0 ,1 ,PROT_NONE , -MAP_PRIVATE_EXCEPT_UCLINUX |MAP_ANONYMOUS ,0 ,0 ); -if (bad_addr ==MAP_FAILED ) -tst_brkm (TBROK |TERRNO , cleanup,"mmap failed" ); - wr_iovec[7 ].iov_base = bad_addr; - -} - -void cleanup (void ) -{ -if (munmap (bad_addr,1 ) ==-1 ) -tst_resm (TBROK |TERRNO ,"munmap failed" ); - -close (fd[0 ]); -close (fd[1 ]); - -if (unlink (f_name) ==-1 ) -tst_resm (TBROK |TERRNO ,"unlink failed" ); - -tst_rmdir (); - -} - -void init_buffs (char *pbufs[]) -{ -int i; - -for (i =0 ; pbufs[i] !=NULL ; i++) { -switch (i) { -case 0 : - -case 1 : -fill_mem (pbufs[i],0 ,1 ); -break ; - -case 2 : -fill_mem (pbufs[i],1 ,0 ); -break ; - -default : -tst_brkm (TBROK , cleanup,"error detected: init_buffs" ); - } - } -} - -int fill_mem (char *c_ptr,int c1,int c2) -{ -int count; - -for (count =1 ; count <=K_1 /CHUNK ; count++) { -if (count &0x01 ) {/* if odd */ -memset (c_ptr, c1,CHUNK ); - }else {/* if even */ -memset (c_ptr, c2,CHUNK ); - } - } -return 0 ; -} - -void sighandler (int sig) -{ -switch (sig) { -case SIGTERM : -break ; - -case SIGPIPE : - in_sighandler++; -return ; - -default : -tst_resm (TFAIL ,"sighandler received invalid signal:%d" , sig); -break ; - } -} +/* +* Copyright (c) International Business Machines Corp., 2001 +* Linux Test Project, 2016 +* +* 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; +*/ + +/* +* DESCRIPTION +* Testcase to check the basic functionality of writev(2) system call. +* Create IO vectors and attempt to writev various components of it. +*/ + +#include <errno.h> +#include <signal.h> +#include <sys/uio.h> +#include "tst_test.h" + +#define CHUNK 64 +#define TESTFILE "writev_data_file" + +static int valid_fd; +static int invalid_fd =-1 ; +static int pipe_fd[2 ]; + +static char buf[CHUNK *4 ]; + +struct iovec iovec_badlen[] = { + { buf,-1 }, + { buf +CHUNK ,CHUNK }, + { buf +CHUNK *2 ,CHUNK }, +}; + +struct iovec iovec_simple[] = { + { buf,CHUNK }, +}; + +struct iovec iovec_zero_null[] = { + { buf,CHUNK }, + { buf +CHUNK ,0 }, + {NULL ,0 }, + {NULL ,0 } +}; + +struct testcase_t { +const char *desc; +int *pfd; +struct iovec (*piovec)[]; +int iovcnt; +int exp_ret; +int exp_errno; +} testcases[] = { + { + .desc ="invalid iov_len" , + .pfd = &valid_fd, + .piovec = &iovec_badlen, + .iovcnt =ARRAY_SIZE (iovec_badlen), + .exp_ret =-1 , + .exp_errno =EINVAL + }, + { + .desc ="invalid fd" , + .pfd = &invalid_fd, + .piovec = &iovec_simple, + .iovcnt =ARRAY_SIZE (iovec_simple), + .exp_ret =-1 , + .exp_errno =EBADF + }, + { + .desc ="invalid iovcnt" , + .pfd = &valid_fd, + .piovec = &iovec_simple, + .iovcnt =-1 , + .exp_ret =-1 , + .exp_errno =EINVAL + }, + { + .desc ="zero iovcnt" , + .pfd = &valid_fd, + .piovec = &iovec_simple, + .iovcnt =0 , + .exp_ret =0 , + }, + { + .desc ="NULL and zero length iovec" , + .pfd = &valid_fd, + .piovec = &iovec_zero_null, + .iovcnt =ARRAY_SIZE (iovec_zero_null), + .exp_ret =CHUNK , + }, + { + .desc ="write to closed pipe" , + .pfd = &(pipe_fd[1 ]), + .piovec = &iovec_simple, + .iovcnt =ARRAY_SIZE (iovec_simple), + .exp_ret =-1 , + .exp_errno =EPIPE , + }, +}; + +void setup (void ) +{ +sigset_t block_mask; + +sigemptyset (&block_mask); +sigaddset (&block_mask,SIGPIPE ); +sigprocmask (SIG_BLOCK , &block_mask,NULL ); + + valid_fd =SAFE_OPEN (TESTFILE ,O_RDWR |O_CREAT ,0644 ); + +SAFE_PIPE (pipe_fd); +SAFE_CLOSE (pipe_fd[0 ]); +} + +static void test_writev (unsigned int i) +{ +struct testcase_t *tcase = &testcases[i]; +int ret; + +TEST (writev (*(tcase->pfd), *(tcase->piovec), tcase->iovcnt)); + + ret = (TEST_RETURN == tcase->exp_ret); +if (TEST_RETURN <0 || tcase->exp_ret <0 ) + ret &= (TEST_ERRNO == tcase->exp_errno); + +if (ret) { +tst_res (TPASS |TTERRNO ,"%s, ret: %ld" , tcase->desc, +TEST_RETURN ); + }else { +tst_res (TPASS |TTERRNO ,"%s, ret: %ld" , tcase->desc, +TEST_RETURN ); + } +} + +static struct tst_test test = { + .tid ="writev01" , + .needs_tmpdir =1 , + .setup = setup, + .test = test_writev, + .tcnt =ARRAY_SIZE (testcases), +};
Signature · 1 line
1.8.3.1
PATCH v2 3/3 writev01: rewrite and drop partially valid iovec tests
Hi!
Quoted 131 lines
testcases/kernel/syscalls/writev/writev01.c +131
-0+/* +* Copyright (c) International Business Machines Corp., 2001 +* Linux Test Project, 2016 +* +* 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; +*/ + +/* +* DESCRIPTION +* Testcase to check the basic functionality of writev(2) system call. +* Create IO vectors and attempt to writev various components of it. +*/ + +#include <errno.h> +#include <signal.h> +#include <sys/uio.h> +#include "tst_test.h" + +#define CHUNK 64 +#define TESTFILE "writev_data_file" + +static int valid_fd; +static int invalid_fd =-1 ; +static int pipe_fd[2 ]; + +static char buf[CHUNK *4 ]; + +struct iovec iovec_badlen[] = { + { buf,-1 }, + { buf +CHUNK ,CHUNK }, + { buf +CHUNK *2 ,CHUNK }, +}; + +struct iovec iovec_simple[] = { + { buf,CHUNK }, +}; + +struct iovec iovec_zero_null[] = { + { buf,CHUNK }, + { buf +CHUNK ,0 }, + {NULL ,0 }, + {NULL ,0 } +}; + +struct testcase_t { +const char *desc; +int *pfd; +struct iovec (*piovec)[]; +int iovcnt; +int exp_ret; +int exp_errno; +} testcases[] = { + { + .desc ="invalid iov_len" , + .pfd = &valid_fd, + .piovec = &iovec_badlen, + .iovcnt =ARRAY_SIZE (iovec_badlen), + .exp_ret =-1 , + .exp_errno =EINVAL + }, + { + .desc ="invalid fd" , + .pfd = &invalid_fd, + .piovec = &iovec_simple, + .iovcnt =ARRAY_SIZE (iovec_simple), + .exp_ret =-1 , + .exp_errno =EBADF + }, + { + .desc ="invalid iovcnt" , + .pfd = &valid_fd, + .piovec = &iovec_simple, + .iovcnt =-1 , + .exp_ret =-1 , + .exp_errno =EINVAL + }, + { + .desc ="zero iovcnt" , + .pfd = &valid_fd, + .piovec = &iovec_simple, + .iovcnt =0 , + .exp_ret =0 , + }, + { + .desc ="NULL and zero length iovec" , + .pfd = &valid_fd, + .piovec = &iovec_zero_null, + .iovcnt =ARRAY_SIZE (iovec_zero_null), + .exp_ret =CHUNK , + }, + { + .desc ="write to closed pipe" , + .pfd = &(pipe_fd[1 ]), + .piovec = &iovec_simple, + .iovcnt =ARRAY_SIZE (iovec_simple), + .exp_ret =-1 , + .exp_errno =EPIPE , + }, +}; + +void setup (void ) +{ +sigset_t block_mask; + +sigemptyset (&block_mask); +sigaddset (&block_mask,SIGPIPE ); +sigprocmask (SIG_BLOCK , &block_mask,NULL ); + + valid_fd =SAFE_OPEN (TESTFILE ,O_RDWR |O_CREAT ,0644 ); + +SAFE_PIPE (pipe_fd); +SAFE_CLOSE (pipe_fd[0 ]); +} + +static void test_writev (unsigned int i) +{ +struct testcase_t *tcase = &testcases[i]; +int ret; + +TEST (writev (*(tcase->pfd), *(tcase->piovec), tcase->iovcnt));
testcases/kernel/syscalls/writev/writev01.c line 141
Quoted 10 lines
testcases/kernel/syscalls/writev/writev01.c +10
-0+ + ret = (TEST_RETURN == tcase->exp_ret); +if (TEST_RETURN <0 || tcase->exp_ret <0 ) + ret &= (TEST_ERRNO == tcase->exp_errno); + +if (ret) { +tst_res (TPASS |TTERRNO ,"%s, ret: %ld" , tcase->desc, +TEST_RETURN ); + }else { + tst_res(TPASS | TTERRNO, "%s, ret: %ld", tcase->desc,
^ TFAIL?
Review
Quoted 2 lines
(quoted diff) +2
-0+ TEST_RETURN); + }
Also I would have created separate functions for failure/success tests so that we can print more informative results, i.e. include the expected errno in the TFAIL result message.
Apart from that this is much better than the original.
Signature · 2 lines
Cyril Hrubis [email protected]
PATCH v2 3/3 writev01: rewrite and drop partially valid iovec tests
Quoted 20 lines · Cyril Hrubis
Quoted 7 lines
testcases/kernel/syscalls/writev/writev01.c +7
-0+ +static void test_writev (unsigned int i) +{ +struct testcase_t *tcase = &testcases[i]; +int ret; + +TEST (writev (*(tcase->pfd), *(tcase->piovec), tcase->iovcnt));testcases/kernel/syscalls/writev/writev01.c line 141
Quoted 10 lines
testcases/kernel/syscalls/writev/writev01.c +10
-0+ + ret = (TEST_RETURN == tcase->exp_ret); +if (TEST_RETURN <0 || tcase->exp_ret <0 ) + ret &= (TEST_ERRNO == tcase->exp_errno); + +if (ret) { +tst_res (TPASS |TTERRNO ,"%s, ret: %ld" , tcase->desc, +TEST_RETURN ); + }else { + tst_res(TPASS | TTERRNO, "%s, ret: %ld", tcase->desc,^ TFAIL?
Quoted 9 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+ TEST_RETURN); + }Also I would have created separate functions for failure/success tests so that we can print more informative results, i.e. include the expected errno in the TFAIL result message.
Apart from that this is much better than the original.
How about:
static void test_writev(unsigned int i)
{
struct testcase_t *tcase = &testcases[i];
int ret;
TEST(writev(*(tcase->pfd), *(tcase->piovec), tcase->iovcnt));
ret = (TEST_RETURN == tcase->exp_ret);
if (TEST_RETURN < 0 || tcase->exp_ret < 0) {
ret &= (TEST_ERRNO == tcase->exp_errno);
tst_res((ret ? TPASS : TFAIL),
"%s, expected: %d (%s), got: %ld (%s)", tcase->desc,
tcase->exp_ret, tst_strerrno(tcase->exp_errno),
TEST_RETURN, tst_strerrno(TEST_ERRNO));
} else {
tst_res((ret ? TPASS : TFAIL),
"%s, expected: %d, got: %ld", tcase->desc,
tcase->exp_ret, TEST_RETURN);
}
}$ ./writev01 tst_test.c:756: INFO: Timeout per run is 0h 05m 00s writev01.c:139: PASS: invalid iov_len, expected: -1 (EINVAL), got: -1 (EINVAL) writev01.c:139: PASS: invalid fd, expected: -1 (EBADF), got: -1 (EBADF) writev01.c:139: PASS: invalid iovcnt, expected: -1 (EINVAL), got: -1 (EINVAL) writev01.c:143: PASS: zero iovcnt, expected: 0, got: 0 writev01.c:143: PASS: NULL and zero length iovec, expected: 64, got: 64 writev01.c:139: PASS: write to closed pipe, expected: -1 (EPIPE), got: -1 (EPIPE)
Regards,
Jan
PATCH v2 3/3 writev01: rewrite and drop partially valid iovec tests
Hi!
Quoted 14 lines
How about:
static void
test_writev(unsigned int i){ struct testcase_t *tcase = &testcases[i]; int ret; TEST(writev(*(tcase->pfd), *(tcase->piovec), tcase->iovcnt)); ret = (TEST_RETURN == tcase->exp_ret); if (TEST_RETURN < 0 || tcase->exp_ret < 0) { ret &= (TEST_ERRNO == tcase->exp_errno); tst_res((ret ? TPASS : TFAIL), "%s, expected: %d (%s), got: %ld (%s)", tcase->desc,
Quoted 8 lines
tcase->exp_ret, tst_strerrno(tcase->exp_errno),
TEST_RETURN, tst_strerrno(TEST_ERRNO));
} else {
tst_res((ret ? TPASS : TFAIL),
"%s, expected: %d, got: %ld", tcase->desc,
tcase->exp_ret, TEST_RETURN);
}
}Looks good.
Signature · 2 lines
Cyril Hrubis [email protected]
PATCH v2 3/3 writev01: rewrite and drop partially valid iovec tests
Quoted 6 lines
Looks good.
--
Cyril Hrubis
[email protected]
Thanks for review, I pushed the series with suggested changes and your ACK.
Regards,
Jan
PATCH v2 1/3 syscalls: new test writev07
In reply to Jan StancekHi!
testcases/kernel/syscalls/writev/writev07.c line 117
Quoted 8 lines
testcases/kernel/syscalls/writev/writev07.c new file +8
-0+/* file content matches written bytes */ +SAFE_LSEEK (fd, initial_file_offset,SEEK_SET ); +SAFE_READ (1 , fd, tmp,TEST_RETURN ); +if (memcmp (tmp, wr_iovec[0 ].iov_base,TEST_RETURN ) ==0 ) { +tst_res (TPASS ,"file has expected content" ); + }else { +tst_res (TFAIL ,"file has unexpected content" ); +tst_res (TINFO ,"expected:" );
^
This TINFO looks redundant now.
Otherwise it looks good, acked.
Signature · 2 lines
Cyril Hrubis [email protected]
PATCH v2 1/3 syscalls: new test writev07
In reply to Jan Stancektestcases/kernel/syscalls/writev/writev07.c line 104
Quoted 9 lines · Jan Stancek
testcases/kernel/syscalls/writev/writev07.c new file +9
-0+ off_after); + +SAFE_CLOSE (fd); +return ; + } + +/* writev() wrote more bytes than bytes preceding invalid iovec */ +tst_res (TINFO ,"writev() has written %ld bytes" ,TEST_RETURN ); +if (TEST_RETURN > (long ) wr_iovec[0 ].iov_base) {
Hi, why TEST_RETURN(the return of writev) compare with wr_iovec[0].iov_base(the address) here?
I run it in armv7 (with printf("TEST_RETURN:%ld, wr_iovec[0].iov_base:%ld\n", TEST_RETURN, (long) wr_iovec[0].iov_base) for debug):
# ./writev07 tst_test.c:760: INFO: Timeout per run is 0h 05m 00s writev07.c:60: INFO: starting test with initial file offset: 0 writev07.c:104: INFO: writev() has written 64 bytes writev07.c:106: FAIL: writev wrote more than expected TEST_RETURN:64, wr_iovec[0].iov_base:-1092708152 writev07.c:60: INFO: starting test with initial file offset: 65 writev07.c:104: INFO: writev() has written 64 bytes writev07.c:106: FAIL: writev wrote more than expected TEST_RETURN:64, wr_iovec[0].iov_base:-1092708152 writev07.c:60: INFO: starting test with initial file offset: 4096 writev07.c:104: INFO: writev() has written 64 bytes writev07.c:106: FAIL: writev wrote more than expected TEST_RETURN:64, wr_iovec[0].iov_base:-1092708152 writev07.c:60: INFO: starting test with initial file offset: 4097 writev07.c:104: INFO: writev() has written 64 bytes writev07.c:106: FAIL: writev wrote more than expected TEST_RETURN:64, wr_iovec[0].iov_base:-1092708144
So the case fail at all time.
Thanks,
Cui Bixuan
Quoted 8 lines
testcases/kernel/syscalls/writev/writev07.c new file +8
-0+tst_res (TFAIL ,"writev wrote more than expected" ); +SAFE_CLOSE (fd); +return ; + } + +/* file content matches written bytes */ +SAFE_LSEEK (fd, initial_file_offset,SEEK_SET ); +SAFE_READ (1 , fd, tmp,TEST_RETURN );
PATCH v2 1/3 syscalls: new test writev07
----- Original Message -----
Quoted 6 lines
From: "Cui Bixuan" <[email protected]>
To: [email protected]
Sent: Thursday, 1 December, 2016 7:36:58 AM
Subject: Re: [LTP] [PATCH v2 1/3] syscalls: new test writev07On 2016/10/7 16:11, Jan Stancek wrote:
Quoted 11 lines
testcases/kernel/syscalls/writev/writev07.c line 104
Quoted 9 lines
testcases/kernel/syscalls/writev/writev07.c new file +9
-0+ off_after); + +SAFE_CLOSE (fd); +return ; + } + +/* writev() wrote more bytes than bytes preceding invalid iovec */ +tst_res (TINFO ,"writev() has written %ld bytes" ,TEST_RETURN ); +if (TEST_RETURN > (long ) wr_iovec[0 ].iov_base) {Hi, why
TEST_RETURN(the return of writev)compare with wr_iovec[0].iov_base(the address) here?
Mistake on my part. That was obviously supposed to compare iovec length. I pushed a fix to change that.
Thanks,
Jan
Quoted 41 lines
I run it in armv7 (with
printf("TEST_RETURN:%ld, wr_iovec[0].iov_base:%ld\n", TEST_RETURN, (long) wr_iovec[0].iov_base)for debug):# ./writev07 tst_test.c:760: INFO: Timeout per run is 0h 05m 00s writev07.c:60: INFO: starting test with initial file offset: 0 writev07.c:104: INFO: writev() has written 64 bytes writev07.c:106: FAIL: writev wrote more than expected TEST_RETURN:64, wr_iovec[0].iov_base:-1092708152 writev07.c:60: INFO: starting test with initial file offset: 65 writev07.c:104: INFO: writev() has written 64 bytes writev07.c:106: FAIL: writev wrote more than expected TEST_RETURN:64, wr_iovec[0].iov_base:-1092708152 writev07.c:60: INFO: starting test with initial file offset: 4096 writev07.c:104: INFO: writev() has written 64 bytes writev07.c:106: FAIL: writev wrote more than expected TEST_RETURN:64, wr_iovec[0].iov_base:-1092708152 writev07.c:60: INFO: starting test with initial file offset: 4097 writev07.c:104: INFO: writev() has written 64 bytes writev07.c:106: FAIL: writev wrote more than expected TEST_RETURN:64, wr_iovec[0].iov_base:-1092708144So the case fail at all time.
Thanks,
Cui Bixuantestcases/kernel/syscalls/writev/writev07.c line 112
Quoted 8 lines
testcases/kernel/syscalls/writev/writev07.c new file +8
-0+tst_res (TFAIL ,"writev wrote more than expected" ); +SAFE_CLOSE (fd); +return ; + } + +/* file content matches written bytes */ +SAFE_LSEEK (fd, initial_file_offset,SEEK_SET ); +SAFE_READ (1 , fd, tmp,TEST_RETURN );--
Mailing list info: https://lists.linux.it/listinfo/ltp