blob: 583ea9bb10e1ca3ab90c85c8a64893a64cdc8b08 [file] [log] [blame]
subrata_modak5d8581f2007-06-20 10:59:49 +00001/*
subrata_modak56207ce2009-03-23 13:35:39 +00002 * Copyright (C) 2007 Monakhov Dmitriy
subrata_modak5d8581f2007-06-20 10:59:49 +00003 *
subrata_modak56207ce2009-03-23 13:35:39 +00004 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
subrata_modak5d8581f2007-06-20 10:59:49 +00008 *
subrata_modak56207ce2009-03-23 13:35:39 +00009 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
12 * the GNU General Public License for more details.
subrata_modak5d8581f2007-06-20 10:59:49 +000013 *
subrata_modak56207ce2009-03-23 13:35:39 +000014 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
Wanlong Gao4548c6c2012-10-19 18:03:36 +080016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
subrata_modak5d8581f2007-06-20 10:59:49 +000017 */
18
19/*
20 * NAME
21 * writev06.c
22 *
23 * DESCRIPTION
24 * These testcases are written to test fault in pages readable
25 * feature in generic write path. Because before actual write
26 * kernel may want check is buffer passed is realy readable.
27 *
28 * USAGE: <for command-line>
29 * writev06 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
30 * where, -c n : Run n copies concurrently.
31 * -e : Turn on errno logging.
32 * -i n : Execute test n times.
33 * -I x : Execute test for x seconds.
34 * -P x : Pause for x seconds between iterations.
35 * -t : Turn on syscall timing.
subrata_modakbdbaec52009-02-26 12:14:51 +000036 *
subrata_modak5d8581f2007-06-20 10:59:49 +000037 * History
38 *
39 * Restrictions
40 * NONE
41 */
42
43#include <sys/types.h>
44#include <signal.h>
45#include <sys/uio.h>
46#include <fcntl.h>
47#include <memory.h>
48#include <errno.h>
Garrett Coopere8530df2010-12-21 11:37:57 -080049#include "test.h"
subrata_modak5d8581f2007-06-20 10:59:49 +000050#include <sys/mman.h>
51
52#define K_1 1024
53#define NBUFS 2
54#define MAX_IOVEC 2
55#define DATA_FILE "writev_data_file"
56
subrata_modak56207ce2009-03-23 13:35:39 +000057int page_size;
subrata_modak5d8581f2007-06-20 10:59:49 +000058
subrata_modak56207ce2009-03-23 13:35:39 +000059char *good_addr[2] = { NULL, NULL };
60char *bad_addr[2] = { NULL, NULL };
subrata_modak5d8581f2007-06-20 10:59:49 +000061
subrata_modak56207ce2009-03-23 13:35:39 +000062struct iovec wr_iovec[MAX_IOVEC] = {
63 {(caddr_t) - 1, 1},
64 {(caddr_t) - 1, 1}
subrata_modak5d8581f2007-06-20 10:59:49 +000065};
66
subrata_modak56207ce2009-03-23 13:35:39 +000067char name[K_1], f_name[K_1];
68int fd[2], in_sighandler;
subrata_modak5d8581f2007-06-20 10:59:49 +000069
70char *TCID = "writev06";
71int TST_TOTAL = 1;
subrata_modak5d8581f2007-06-20 10:59:49 +000072
73void sighandler(int);
74void setup(void);
75void cleanup(void);
76int fail;
77
78int main(int argc, char **argv)
79{
Cyril Hrubis89af32a2012-10-24 16:39:11 +020080 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020081 const char *msg;
subrata_modak5d8581f2007-06-20 10:59:49 +000082
Garrett Cooper45e285d2010-11-22 12:19:25 -080083 if ((msg = parse_opts(argc, argv, NULL, NULL)) != NULL) {
subrata_modak5d8581f2007-06-20 10:59:49 +000084 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
Garrett Cooper2c282152010-12-16 00:55:50 -080085
subrata_modak5d8581f2007-06-20 10:59:49 +000086 }
87
subrata_modak56207ce2009-03-23 13:35:39 +000088 setup(); /* set "tstdir", and "testfile" vars */
subrata_modak5d8581f2007-06-20 10:59:49 +000089
90 /* The following loop checks looping state if -i option given */
91 for (lc = 0; TEST_LOOPING(lc); lc++) {
92
Caspar Zhangd59a6592013-03-07 14:59:12 +080093 /* reset tst_count in case we are looping */
94 tst_count = 0;
subrata_modak5d8581f2007-06-20 10:59:49 +000095
subrata_modak56207ce2009-03-23 13:35:39 +000096 fd[1] = -1; /* Invalid file descriptor */
subrata_modak5d8581f2007-06-20 10:59:49 +000097
98 if (signal(SIGTERM, sighandler) == SIG_ERR) {
99 perror("signal");
100 tst_resm(TFAIL, "signal() SIGTERM FAILED");
101 cleanup();
Garrett Cooper2c282152010-12-16 00:55:50 -0800102
subrata_modak5d8581f2007-06-20 10:59:49 +0000103 }
104
105 if (signal(SIGPIPE, sighandler) == SIG_ERR) {
106 perror("signal");
107 tst_resm(TFAIL, "signal() SIGPIPE FAILED");
108 cleanup();
Garrett Cooper2c282152010-12-16 00:55:50 -0800109
subrata_modak5d8581f2007-06-20 10:59:49 +0000110 }
111
112 if ((fd[0] = open(f_name, O_WRONLY | O_CREAT, 0666)) < 0) {
113 tst_resm(TFAIL, "open(2) failed: fname = %s, "
114 "errno = %d", f_name, errno);
115 cleanup();
Garrett Cooper2c282152010-12-16 00:55:50 -0800116
subrata_modak5d8581f2007-06-20 10:59:49 +0000117 }
subrata_modak56207ce2009-03-23 13:35:39 +0000118
119 /*
subrata_modak5d8581f2007-06-20 10:59:49 +0000120 * Iovecs passed to writev points to valid (readable) regions,
subrata_modak56207ce2009-03-23 13:35:39 +0000121 * so all bytes must be successfully written.
subrata_modak5d8581f2007-06-20 10:59:49 +0000122 */
123//block1:
124
125 tst_resm(TINFO, "Enter block 1");
126 fail = 0;
subrata_modak56207ce2009-03-23 13:35:39 +0000127
subrata_modak5d8581f2007-06-20 10:59:49 +0000128 TEST(writev(fd[0], wr_iovec, 2));
subrata_modak56207ce2009-03-23 13:35:39 +0000129 if (TEST_RETURN >= 0) {
subrata_modak5d8581f2007-06-20 10:59:49 +0000130 if (TEST_RETURN == 2) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800131 tst_resm(TINFO,
132 "writev returned %d as expected", 2);
subrata_modak5d8581f2007-06-20 10:59:49 +0000133 } else {
134 tst_resm(TFAIL, "Expected nbytes = %d, got "
subrata_modak923b23f2009-11-02 13:57:16 +0000135 "%ld", 2, TEST_RETURN);
subrata_modak5d8581f2007-06-20 10:59:49 +0000136 fail = 1;
137 }
138 } else {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800139 tst_resm(TFAIL | TTERRNO,
140 "Error writev return value = %ld",
subrata_modak923b23f2009-11-02 13:57:16 +0000141 TEST_RETURN);
subrata_modak5d8581f2007-06-20 10:59:49 +0000142 fail = 1;
143 }
144 if (fail) {
145 tst_resm(TINFO, "block 1 FAILED");
146 } else {
147 tst_resm(TINFO, "block 1 PASSED");
148 }
149 tst_resm(TINFO, "Exit block 1");
150 }
151 cleanup();
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800152 tst_exit();
Garrett Cooper2c282152010-12-16 00:55:50 -0800153
subrata_modak5d8581f2007-06-20 10:59:49 +0000154}
155
156/*
157 * setup()
158 * performs all ONE TIME setup for this test
159 */
subrata_modak56207ce2009-03-23 13:35:39 +0000160void setup(void)
subrata_modak5d8581f2007-06-20 10:59:49 +0000161{
Garrett Cooper2c282152010-12-16 00:55:50 -0800162
subrata_modak5d8581f2007-06-20 10:59:49 +0000163 tst_sig(FORK, DEF_HANDLER, cleanup);
164
subrata_modak5d8581f2007-06-20 10:59:49 +0000165 /* Pause if that option was specified.
166 * TEST_PAUSE contains the code to fork the test with the -i option.
167 * You want to make sure you do this before you create your temporary
168 * directory.
169 */
170 TEST_PAUSE;
171
172 /* Create a unique temporary directory and chdir() to it. */
173 tst_tmpdir();
174
175 strcpy(name, DATA_FILE);
176 sprintf(f_name, "%s.%d", name, getpid());
177
178 page_size = getpagesize();
179
180 /* Crate two readable and writeble mappings with non reabable
181 * mapping around */
182 bad_addr[0] = mmap(NULL, page_size * 3, PROT_NONE,
subrata_modak56207ce2009-03-23 13:35:39 +0000183 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
subrata_modak76e1c912009-03-18 08:31:06 +0000184 if (bad_addr[0] == MAP_FAILED)
subrata_modak56207ce2009-03-23 13:35:39 +0000185 tst_brkm(TBROK, cleanup, "mmap failed for bad_addr[0]");
subrata_modak76e1c912009-03-18 08:31:06 +0000186
subrata_modak56207ce2009-03-23 13:35:39 +0000187 good_addr[0] = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
188 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
subrata_modak76e1c912009-03-18 08:31:06 +0000189 if (good_addr[0] == MAP_FAILED)
190 tst_brkm(TBROK, cleanup, "mmap failed for good_addr[0]");
191
subrata_modak5d8581f2007-06-20 10:59:49 +0000192 bad_addr[1] = mmap(NULL, page_size * 3, PROT_NONE,
subrata_modak56207ce2009-03-23 13:35:39 +0000193 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
subrata_modak76e1c912009-03-18 08:31:06 +0000194 if (bad_addr[1] == MAP_FAILED)
195 tst_brkm(TBROK, cleanup, "mmap failed for bad_addr[1]");
196
subrata_modak56207ce2009-03-23 13:35:39 +0000197 good_addr[1] = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
198 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
subrata_modak76e1c912009-03-18 08:31:06 +0000199 if (good_addr[1] == MAP_FAILED)
200 tst_brkm(TBROK, cleanup, "mmap failed for good_addr[1]");
201
subrata_modak56207ce2009-03-23 13:35:39 +0000202 /* force page fault for writable mappings */
203 memset(good_addr[0], 'a', page_size);
204 memset(good_addr[1], 'b', page_size);
subrata_modak5d8581f2007-06-20 10:59:49 +0000205
subrata_modak56207ce2009-03-23 13:35:39 +0000206 wr_iovec[0].iov_base = good_addr[0] + page_size - 1;
subrata_modak5d8581f2007-06-20 10:59:49 +0000207 wr_iovec[1].iov_base = good_addr[1] + page_size - 1;
208
subrata_modak5d8581f2007-06-20 10:59:49 +0000209}
210
211/*
212 * cleanup()
213 * performs all ONE TIME cleanup for this test at
214 * completion or premature exit
215 */
subrata_modak56207ce2009-03-23 13:35:39 +0000216void cleanup(void)
subrata_modak5d8581f2007-06-20 10:59:49 +0000217{
subrata_modak5d8581f2007-06-20 10:59:49 +0000218
subrata_modak3fddbf62007-11-14 15:27:56 +0000219 close(fd[0]);
220
subrata_modak5d8581f2007-06-20 10:59:49 +0000221 if (unlink(f_name) < 0) {
222 tst_resm(TFAIL, "unlink Failed--file = %s, errno = %d",
223 f_name, errno);
224 }
225 tst_rmdir();
226
subrata_modak5d8581f2007-06-20 10:59:49 +0000227}
228
229/*
230 * sighandler()
231 * Signal handler for SIGTERM and SIGPIPE
232 */
subrata_modak56207ce2009-03-23 13:35:39 +0000233void sighandler(int sig)
subrata_modak5d8581f2007-06-20 10:59:49 +0000234{
subrata_modak56207ce2009-03-23 13:35:39 +0000235 switch (sig) {
236 case SIGTERM:
237 break;
238 case SIGPIPE:
239 ++in_sighandler;
240 return;
subrata_modak5d8581f2007-06-20 10:59:49 +0000241 default:
subrata_modak56207ce2009-03-23 13:35:39 +0000242 tst_resm(TFAIL, "sighandler() received invalid signal "
243 ": %d", sig);
244 break;
subrata_modak5d8581f2007-06-20 10:59:49 +0000245 }
246
247 if ((unlink(f_name) < 0) && (errno != ENOENT)) {
248 tst_resm(TFAIL, "unlink Failed--file = %s, errno = %d",
249 f_name, errno);
250 cleanup();
Garrett Cooper2c282152010-12-16 00:55:50 -0800251
subrata_modak5d8581f2007-06-20 10:59:49 +0000252 }
253 exit(sig);
Chris Dearmanec6edca2012-10-17 19:54:01 -0700254}