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