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