• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) International Business Machines  Corp., 2001
3  * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of
8  * the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it would be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write the Free Software Foundation,
17  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  *
19  * This is the main of your user space test program,
20  * which will open the correct kernel bioule, find the
21  * file descriptor value and use that value to make
22  * ioctl calls to the system
23  *
24  * Use the ki_generic and other ki_testname functions
25  * to abstract the calls from the main
26  *
27  *  FILE        : user_tbio.c
28  *  USAGE       : kernel_space:./load_tbio.sh
29  *                user_space  :./test_bio
30  *
31  *  DESCRIPTION : The bioule will test block i/o layer for kernel 2.5
32  *  REQUIREMENTS:
33  *                1) glibc 2.1.91 or above.
34  *
35  *  HISTORY     :
36  *      11/19/2003 Kai Zhao (ltcd3@cn.ibm.com)
37  *
38  *  CODE COVERAGE: 74.9% - fs/bio.c (Total Coverage)
39  *
40  */
41 
42 #define _GNU_SOURCE
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <sys/stat.h>
46 #include <sys/ioctl.h>
47 #include <fcntl.h>
48 #include <errno.h>
49 #include <sys/sysmacros.h>
50 #include <sys/types.h>
51 #include <linux/kernel.h>
52 #include <unistd.h>
53 #include <string.h>
54 
55 #include "test.h"
56 #include "safe_macros.h"
57 #include "old_module.h"
58 
59 #include "../tbio_kernel/tbio.h"
60 
61 char *TCID = TBIO_DEVICE_NAME;
62 
63 static const char module_name[]	= "ltp_tbio.ko";
64 static int module_loaded;
65 static int tbio_fd = -1;
66 
cleanup(void)67 void cleanup(void)
68 {
69 
70 	if (tbio_fd != -1) {
71 		close(tbio_fd);
72 		tbio_fd = -1;
73 	}
74 
75 	if (module_loaded)
76 		tst_module_unload(NULL, module_name);
77 
78 	if (unlink(DEVICE_NAME) && (errno != ENOENT))
79 		tst_brkm(TBROK | TERRNO, NULL, "unlink failed");
80 }
81 
82 
setup(void)83 void setup(void)
84 {
85 	dev_t devt;
86 	struct stat st;
87 	unsigned int i, valid_node_created;
88 
89 	tst_require_root();
90 
91 	if (tst_kvercmp(2, 6, 0) < 0) {
92 		tst_brkm(TCONF, NULL,
93 			"Test must be run with kernel 2.6 or newer");
94 	}
95 
96 	tst_module_load(cleanup, module_name, NULL);
97 	module_loaded = 1;
98 
99 	SAFE_FILE_SCANF(cleanup, "/sys/class/block/tbio/dev",
100 		"%d:0", &TBIO_MAJOR);
101 
102 	devt = makedev(TBIO_MAJOR, 0);
103 
104 	/*
105 	 * Wait until udev creates the device node.
106 	 * If the node is not created or invalid, create it manually.
107 	 */
108 	valid_node_created = 0;
109 	for (i = 0; i < 50; i++) {
110 		if (stat(DEVICE_NAME, &st)) {
111 			if (errno != ENOENT)
112 				tst_brkm(TBROK | TERRNO, cleanup,
113 					 "stat() failed");
114 		} else {
115 			if ((st.st_mode & S_IFBLK) && (st.st_rdev == devt)) {
116 				valid_node_created = 1;
117 				break;
118 			}
119 		}
120 
121 		usleep(100000);
122 	}
123 
124 	if (!valid_node_created) {
125 		tst_resm(TINFO,
126 			 "The device file was not created by udev, "
127 			 "proceeding with manual creation");
128 
129 		if (unlink(DEVICE_NAME) && (errno != ENOENT))
130 			tst_brkm(TBROK | TERRNO, cleanup, "unlink() failed");
131 		if (mknod(DEVICE_NAME, S_IFBLK | S_IRUSR | S_IWUSR |
132 			  S_IRGRP | S_IWGRP, devt))
133 			tst_brkm(TBROK | TERRNO, cleanup, "mknod() failed");
134 	}
135 
136 	tbio_fd = SAFE_OPEN(cleanup, DEVICE_NAME, O_RDWR);
137 
138 	tst_resm(TINFO, "Device opened successfully ");
139 }
140 
141 
tbio_to_dev(int fd,int flag)142 int tbio_to_dev(int fd, int flag)
143 {
144 	int rc;
145 	tbio_interface_t bif;
146 
147 	memset(&bif, 0, sizeof(tbio_interface_t));
148 	rc = posix_memalign(&bif.data, 512, 1024);
149 	if (rc) {
150 		tst_resm(TINFO, "posix_memalign failed");
151 		return -1;
152 	}
153 
154 	strcpy(bif.data, "User space data");
155 	bif.data_len = 1024;
156 	bif.direction = TBIO_TO_DEV;
157 	bif.cmd = SAFE_MALLOC(cleanup, 6);
158 	if (bif.cmd == NULL) {
159 		tst_resm(TINFO, "malloc cmd space failed");
160 		free(bif.data);
161 		return -1;
162 	}
163 	strcpy(bif.cmd, "WRITE");
164 	bif.cmd_len = 6;
165 
166 	rc = ioctl(fd, flag, &bif);
167 	if (rc) {
168 		free(bif.data);
169 		free(bif.cmd);
170 		tst_resm(TINFO, "Ioctl error for TBIO_TO_DEV");
171 		return rc;
172 	}
173 
174 	free(bif.data);
175 	free(bif.cmd);
176 
177 	return 0;
178 
179 }
180 
tbio_from_dev(int fd,int flag)181 int tbio_from_dev(int fd, int flag)
182 {
183 	int rc;
184 	tbio_interface_t bif;
185 
186 	memset(&bif, 0, sizeof(tbio_interface_t));
187 	rc = posix_memalign(&bif.data, 512, 1024);
188 	if (rc) {
189 		tst_resm(TINFO, "posix_memalign failed");
190 		return -1;
191 	}
192 
193 	memset(bif.data, 0, 1024);
194 
195 	bif.data_len = 1024;
196 	bif.direction = TBIO_FROM_DEV;
197 	bif.cmd = SAFE_MALLOC(cleanup, 5);
198 	if (bif.cmd == NULL) {
199 		tst_resm(TINFO, "malloc cmd space failed");
200 		free(bif.data);
201 		return -1;
202 	}
203 	strcpy(bif.cmd, "READ");
204 	bif.cmd_len = 5;
205 
206 	rc = ioctl(fd, flag, &bif);
207 	if (rc) {
208 		free(bif.data);
209 		free(bif.cmd);
210 		tst_resm(TINFO, "Ioctl error for TBIO_TO_DEV");
211 		return rc;
212 	}
213 
214 	if (strcmp(bif.data, "User space data")) {
215 		tst_resm(TINFO, "TBIO_FROM_DEV failed");
216 		free(bif.data);
217 		free(bif.cmd);
218 		return -1;
219 	}
220 
221 	free(bif.data);
222 	free(bif.cmd);
223 
224 	return 0;
225 
226 }
227 
tbio_split_to_dev(int fd,int flag)228 int tbio_split_to_dev(int fd, int flag)
229 {
230 	int rc;
231 	tbio_interface_t bif;
232 
233 	memset(&bif, 0, sizeof(tbio_interface_t));
234 	rc = posix_memalign(&bif.data, 512, 2048);
235 	if (rc) {
236 		tst_resm(TINFO, "posix_memalign failed");
237 		return -1;
238 	}
239 
240 	strcpy(bif.data, "User space data");
241 	bif.data_len = 2048;
242 	bif.direction = TBIO_TO_DEV;
243 	bif.cmd = SAFE_MALLOC(cleanup, 6);
244 	if (bif.cmd == NULL) {
245 		tst_resm(TINFO, "malloc cmd space failed");
246 		free(bif.data);
247 		return -1;
248 	}
249 	strcpy(bif.cmd, "WRITE");
250 	bif.cmd_len = 6;
251 
252 	rc = ioctl(fd, flag, &bif);
253 	if (rc) {
254 		free(bif.data);
255 		free(bif.cmd);
256 		tst_resm(TINFO, "Ioctl error for TBIO_TO_DEV");
257 		return rc;
258 	}
259 
260 	free(bif.data);
261 	free(bif.cmd);
262 
263 	return 0;
264 
265 }
266 
ki_generic(int fd,int flag)267 int ki_generic(int fd, int flag)
268 {
269 	tbio_interface_t bif;
270 
271 	int rc = ioctl(fd, flag, &bif);
272 	if (rc)
273 		tst_resm(TINFO | TERRNO, "ioctl error");
274 
275 	return rc;
276 }
277 
278 
main(void)279 int main(void)
280 {
281 	setup();
282 
283 	if (ki_generic(tbio_fd, LTP_TBIO_ALLOC))
284 		tst_resm(TFAIL, "failed on LTP_TBIO_ALLOC test");
285 	else
286 		tst_resm(TPASS, "success on LTP_TBIO_ALLOC test");
287 
288 	if (ki_generic(tbio_fd, LTP_TBIO_CLONE))
289 		tst_resm(TFAIL, "failed on LTP_TBIO_CLONE test");
290 	else
291 		tst_resm(TPASS, "success on LTP_TBIO_CLONE test");
292 
293 	if (ki_generic(tbio_fd, LTP_TBIO_GET_NR_VECS))
294 		tst_resm(TFAIL, "failed on LTP_TBIO_GET_NR_VECS test");
295 	else
296 		tst_resm(TPASS, "success on LTP_TBIO_GET_NR_VECS test");
297 
298 	if (ki_generic(tbio_fd, LTP_TBIO_ADD_PAGE))
299 		tst_resm(TFAIL, "failed on LTP_TBIO_ADD_PAGE test");
300 	else
301 		tst_resm(TPASS, "success on LTP_TBIO_ADD_PAGE test");
302 
303 	if (tbio_split_to_dev(tbio_fd, LTP_TBIO_SPLIT))
304 		tst_resm(TFAIL, "failed on LTP_TBIO_SPLIT:write to dev");
305 	else
306 		tst_resm(TPASS, "success on LTP_TBIO_SPLIT:write to dev");
307 
308 	if (tbio_to_dev(tbio_fd, LTP_TBIO_DO_IO))
309 		tst_resm(TFAIL, "failed on LTP_TBIO_DO_IO:write to dev");
310 	else
311 		tst_resm(TPASS, "success on LTP_TBIO_DO_IO:write to dev");
312 
313 	if (tbio_from_dev(tbio_fd, LTP_TBIO_DO_IO))
314 		tst_resm(TFAIL, "failed on LTP_TBIO_DO_IO:read from dev");
315 	else
316 		tst_resm(TPASS, "success on LTP_TBIO_DO_IO:read from dev");
317 
318 	if (ki_generic(tbio_fd, LTP_TBIO_PUT))
319 		tst_resm(TFAIL, "failed on LTP_TBIO_PUT test");
320 	else
321 		tst_resm(TPASS, "success on LTP_TBIO_PUT test");
322 
323 	cleanup();
324 
325 	tst_exit();
326 }
327