Home | History | Annotate | Download | only in tbio_user
      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 (at) 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 
     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 
     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 
    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 
    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 
    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 
    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 
    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