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/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 
     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 
     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 
    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 
    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 
    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 
    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 
    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