• 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/types.h>
50 #include <linux/kernel.h>
51 #include <unistd.h>
52 #include <string.h>
53 
54 #include "test.h"
55 #include "safe_macros.h"
56 #include "old_module.h"
57 
58 #include "../tbio_kernel/tbio.h"
59 
60 char *TCID = TBIO_DEVICE_NAME;
61 
62 static const char module_name[]	= "ltp_tbio.ko";
63 static int module_loaded;
64 static int tbio_fd = -1;
65 
cleanup(void)66 void cleanup(void)
67 {
68 
69 	if (tbio_fd != -1) {
70 		close(tbio_fd);
71 		tbio_fd = -1;
72 	}
73 
74 	if (module_loaded)
75 		tst_module_unload(NULL, module_name);
76 
77 	if (unlink(DEVICE_NAME) && (errno != ENOENT))
78 		tst_brkm(TBROK | TERRNO, NULL, "unlink failed");
79 }
80 
81 
setup(void)82 void setup(void)
83 {
84 	dev_t devt;
85 	struct stat st;
86 	unsigned int i, valid_node_created;
87 
88 	tst_require_root();
89 
90 	if (tst_kvercmp(2, 6, 0) < 0) {
91 		tst_brkm(TCONF, NULL,
92 			"Test must be run with kernel 2.6 or newer");
93 	}
94 
95 	tst_module_load(cleanup, module_name, NULL);
96 	module_loaded = 1;
97 
98 	SAFE_FILE_SCANF(cleanup, "/sys/class/block/tbio/dev",
99 		"%d:0", &TBIO_MAJOR);
100 
101 	devt = makedev(TBIO_MAJOR, 0);
102 
103 	/*
104 	 * Wait until udev creates the device node.
105 	 * If the node is not created or invalid, create it manually.
106 	 */
107 	valid_node_created = 0;
108 	for (i = 0; i < 50; i++) {
109 		if (stat(DEVICE_NAME, &st)) {
110 			if (errno != ENOENT)
111 				tst_brkm(TBROK | TERRNO, cleanup,
112 					 "stat() failed");
113 		} else {
114 			if ((st.st_mode & S_IFBLK) && (st.st_rdev == devt)) {
115 				valid_node_created = 1;
116 				break;
117 			}
118 		}
119 
120 		usleep(100000);
121 	}
122 
123 	if (!valid_node_created) {
124 		tst_resm(TINFO,
125 			 "The device file was not created by udev, "
126 			 "proceeding with manual creation");
127 
128 		if (unlink(DEVICE_NAME) && (errno != ENOENT))
129 			tst_brkm(TBROK | TERRNO, cleanup, "unlink() failed");
130 		if (mknod(DEVICE_NAME, S_IFBLK | S_IRUSR | S_IWUSR |
131 			  S_IRGRP | S_IWGRP, devt))
132 			tst_brkm(TBROK | TERRNO, cleanup, "mknod() failed");
133 	}
134 
135 	tbio_fd = open(DEVICE_NAME, O_RDWR);
136 	if (tbio_fd < 0) {
137 		tst_brkm(TBROK | TERRNO, cleanup, "open of %s failed",
138 			DEVICE_NAME);
139 	}
140 
141 	tst_resm(TINFO, "Device opened successfully ");
142 }
143 
144 
tbio_to_dev(int fd,int flag)145 int tbio_to_dev(int fd, int flag)
146 {
147 	int rc;
148 	tbio_interface_t bif;
149 
150 	memset(&bif, 0, sizeof(tbio_interface_t));
151 	rc = posix_memalign(&bif.data, 512, 1024);
152 	if (rc) {
153 		tst_resm(TINFO, "posix_memalign failed");
154 		return -1;
155 	}
156 
157 	strcpy(bif.data, "User space data");
158 	bif.data_len = 1024;
159 	bif.direction = TBIO_TO_DEV;
160 	bif.cmd = SAFE_MALLOC(cleanup, 6);
161 	if (bif.cmd == NULL) {
162 		tst_resm(TINFO, "malloc cmd space failed");
163 		free(bif.data);
164 		return -1;
165 	}
166 	strcpy(bif.cmd, "WRITE");
167 	bif.cmd_len = 6;
168 
169 	rc = ioctl(fd, flag, &bif);
170 	if (rc) {
171 		free(bif.data);
172 		free(bif.cmd);
173 		tst_resm(TINFO, "Ioctl error for TBIO_TO_DEV");
174 		return rc;
175 	}
176 
177 	free(bif.data);
178 	free(bif.cmd);
179 
180 	return 0;
181 
182 }
183 
tbio_from_dev(int fd,int flag)184 int tbio_from_dev(int fd, int flag)
185 {
186 	int rc;
187 	tbio_interface_t bif;
188 
189 	memset(&bif, 0, sizeof(tbio_interface_t));
190 	rc = posix_memalign(&bif.data, 512, 1024);
191 	if (rc) {
192 		tst_resm(TINFO, "posix_memalign failed");
193 		return -1;
194 	}
195 
196 	memset(bif.data, 0, 1024);
197 
198 	bif.data_len = 1024;
199 	bif.direction = TBIO_FROM_DEV;
200 	bif.cmd = SAFE_MALLOC(cleanup, 5);
201 	if (bif.cmd == NULL) {
202 		tst_resm(TINFO, "malloc cmd space failed");
203 		free(bif.data);
204 		return -1;
205 	}
206 	strcpy(bif.cmd, "READ");
207 	bif.cmd_len = 5;
208 
209 	rc = ioctl(fd, flag, &bif);
210 	if (rc) {
211 		free(bif.data);
212 		free(bif.cmd);
213 		tst_resm(TINFO, "Ioctl error for TBIO_TO_DEV");
214 		return rc;
215 	}
216 
217 	if (strcmp(bif.data, "User space data")) {
218 		tst_resm(TINFO, "TBIO_FROM_DEV failed");
219 		free(bif.data);
220 		free(bif.cmd);
221 		return -1;
222 	}
223 
224 	free(bif.data);
225 	free(bif.cmd);
226 
227 	return 0;
228 
229 }
230 
tbio_split_to_dev(int fd,int flag)231 int tbio_split_to_dev(int fd, int flag)
232 {
233 	int rc;
234 	tbio_interface_t bif;
235 
236 	memset(&bif, 0, sizeof(tbio_interface_t));
237 	rc = posix_memalign(&bif.data, 512, 2048);
238 	if (rc) {
239 		tst_resm(TINFO, "posix_memalign failed");
240 		return -1;
241 	}
242 
243 	strcpy(bif.data, "User space data");
244 	bif.data_len = 2048;
245 	bif.direction = TBIO_TO_DEV;
246 	bif.cmd = SAFE_MALLOC(cleanup, 6);
247 	if (bif.cmd == NULL) {
248 		tst_resm(TINFO, "malloc cmd space failed");
249 		free(bif.data);
250 		return -1;
251 	}
252 	strcpy(bif.cmd, "WRITE");
253 	bif.cmd_len = 6;
254 
255 	rc = ioctl(fd, flag, &bif);
256 	if (rc) {
257 		free(bif.data);
258 		free(bif.cmd);
259 		tst_resm(TINFO, "Ioctl error for TBIO_TO_DEV");
260 		return rc;
261 	}
262 
263 	free(bif.data);
264 	free(bif.cmd);
265 
266 	return 0;
267 
268 }
269 
ki_generic(int fd,int flag)270 int ki_generic(int fd, int flag)
271 {
272 	tbio_interface_t bif;
273 
274 	int rc = ioctl(fd, flag, &bif);
275 	if (rc)
276 		tst_resm(TINFO | TERRNO, "ioctl error");
277 
278 	return rc;
279 }
280 
281 
main(void)282 int main(void)
283 {
284 	setup();
285 
286 	if (ki_generic(tbio_fd, LTP_TBIO_ALLOC))
287 		tst_resm(TFAIL, "failed on LTP_TBIO_ALLOC test");
288 	else
289 		tst_resm(TPASS, "success on LTP_TBIO_ALLOC test");
290 
291 	if (ki_generic(tbio_fd, LTP_TBIO_CLONE))
292 		tst_resm(TFAIL, "failed on LTP_TBIO_CLONE test");
293 	else
294 		tst_resm(TPASS, "success on LTP_TBIO_CLONE test");
295 
296 	if (ki_generic(tbio_fd, LTP_TBIO_GET_NR_VECS))
297 		tst_resm(TFAIL, "failed on LTP_TBIO_GET_NR_VECS test");
298 	else
299 		tst_resm(TPASS, "success on LTP_TBIO_GET_NR_VECS test");
300 
301 	if (ki_generic(tbio_fd, LTP_TBIO_ADD_PAGE))
302 		tst_resm(TFAIL, "failed on LTP_TBIO_ADD_PAGE test");
303 	else
304 		tst_resm(TPASS, "success on LTP_TBIO_ADD_PAGE test");
305 
306 	if (tbio_split_to_dev(tbio_fd, LTP_TBIO_SPLIT))
307 		tst_resm(TFAIL, "failed on LTP_TBIO_SPLIT:write to dev");
308 	else
309 		tst_resm(TPASS, "success on LTP_TBIO_SPLIT:write to dev");
310 
311 	if (tbio_to_dev(tbio_fd, LTP_TBIO_DO_IO))
312 		tst_resm(TFAIL, "failed on LTP_TBIO_DO_IO:write to dev");
313 	else
314 		tst_resm(TPASS, "success on LTP_TBIO_DO_IO:write to dev");
315 
316 	if (tbio_from_dev(tbio_fd, LTP_TBIO_DO_IO))
317 		tst_resm(TFAIL, "failed on LTP_TBIO_DO_IO:read from dev");
318 	else
319 		tst_resm(TPASS, "success on LTP_TBIO_DO_IO:read from dev");
320 
321 	if (ki_generic(tbio_fd, LTP_TBIO_PUT))
322 		tst_resm(TFAIL, "failed on LTP_TBIO_PUT test");
323 	else
324 		tst_resm(TPASS, "success on LTP_TBIO_PUT test");
325 
326 	cleanup();
327 
328 	tst_exit();
329 }
330