int test_spio_vluns(int cmd) { int rc; int i,j; int cfdisk = 0; struct flash_disk fldisks[MAX_FDISK]; //__u64 chunk; cfdisk = get_flash_disks(fldisks, FDISKS_ALL); char *str = getenv("LONG_RUN"); if (str == NULL) { //non regression if (cfdisk > 3) cfdisk=3; } for (i = 0; i< cfdisk; i++) { //create atleast 10 chunks on each on PLUN for (j=0; j < 10; j++) { if (0 == fork()) //child process { rc = test_spio_lun(fldisks[i].dev, fldisks[i].devno[0], LUN_VIRTUAL,chunks[j%10]); exit(rc); } } } rc = wait4all(); return rc; }
int test_spio_direct_virtual() { int rc=0; int j; int cfdisk = 0; struct flash_disk fldisks[MAX_FDISK]; //__u64 chunk; int count = 1; int procces=10; int index = 0; //to switch flash disks for VLUN & PLUN IO char *str = getenv("LONG_RUN"); if (str != NULL) { printf("LONG_RUN enabled...\n"); count = 10; } cfdisk = get_flash_disks(fldisks, FDISKS_ALL); if (cfdisk < 2) { fprintf(stderr,"Must have 2 flash disks..\n"); return -1; } while (count-- >0) { if (0 == fork()) { rc = test_spio_lun(fldisks[index].dev, fldisks[index].devno[0],LUN_DIRECT,0); exit(rc); } //create atleast 10 chunks on each on PLUN index = (index+1)%2; for (j=0; j < procces; j++) { if (0 == fork()) //child process { //here you can change the path ids later rc = test_spio_lun(fldisks[index].dev, fldisks[index].devno[0], LUN_VIRTUAL,chunks[j]); exit(rc); } } rc = wait4all(); CHECK_RC(rc, "wait4all failed"); printf("%d loop remain................\n",count); } return rc; }
int test_spio_attach_detach(int cmd) { int rc; int i; int cfdisk = 0; struct flash_disk disks[MAX_FDISK]; __u64 chunk = 32; cfdisk = get_flash_disks(disks, FDISKS_ALL); if (cfdisk < 2) { fprintf(stderr,"Must have 2 flash disks..\n"); return -1; } if (fork() == 0) { //child process if (cmd == 1) { //virtual IO for (i=0;i<cfdisk;i++) { if (!strcmp(cflash_path, disks[i].dev)) { strcpy(disks[0].dev,disks[i].dev); disks[0].devno[0] = disks[i].devno[0]; } } rc = create_ctx_process(disks[0].dev,disks[0].devno[0],chunk); } else { //direct IO rc = test_spio_lun(disks[1].dev, disks[1].devno[0], LUN_DIRECT,0); } exit(rc); } //let parent process do detach & attach for another context id if (cmd == 1) { rc = do_attach_detach(disks[0].dev, disks[0].devno[0], LUN_VIRTUAL); } else { rc = do_attach_detach(disks[0].dev, disks[0].devno[0], LUN_DIRECT); } rc |= wait4all(); return rc; }
// 7.1.217 : create two context for same flash disks shared between 2 adapters int test_cfdisk_ctxs_diff_devno() { int nDisk; int rc=0; struct flash_disk cfDisk[2]; struct ctx myctx1, myctx2; struct ctx *p_ctx1 = &myctx1; struct ctx *p_ctx2 = &myctx2; pid = getpid(); nDisk = get_flash_disks(cfDisk, FDISKS_DIFF_ADPTR); if (nDisk < 2) { fprintf(stderr,"Failed to find 2 flash disks from diff adapter..\n"); return -1; } // On AIX both dev will have same name // On Linux both dev will have diff name rc = ctx_init2(p_ctx1, cfDisk[0].dev, DK_AF_ASSIGN_AFU, cfDisk[0].devno[0]); CHECK_RC(rc, "p_ctx1 Context init failed"); rc = ctx_init2(p_ctx2, cfDisk[1].dev, DK_AF_ASSIGN_AFU, cfDisk[1].devno[0]); CHECK_RC(rc, "p_ctx2 Context init failed"); rc = create_resource(p_ctx1, 0, DK_UDF_ASSIGN_PATH, LUN_DIRECT); CHECK_RC(rc, "create LUN_DIRECT for p_ctx1 failed"); rc = create_resource(p_ctx2, 0, DK_UDF_ASSIGN_PATH, LUN_DIRECT); CHECK_RC(rc, "create LUN_DIRECT for p_ctx2 failed"); cleanup(p_ctx1, -1); cleanup(p_ctx2, -1); return 0; }
int test_spio_pluns(int cmd) { int rc; int i; int cfdisk = 0; struct flash_disk fldisks[MAX_FDISK]; cfdisk = get_flash_disks(fldisks, FDISKS_ALL); if (cfdisk <= 0) { fprintf(stderr, "NO Cflash disks found\n"); return -1; } char *str = getenv("LONG_RUN"); if (str == NULL) { //non regression if (cfdisk > 4) cfdisk=4; } for (i = 0; i<cfdisk; i++) { if (0 == fork()) //child process { rc = test_spio_lun(fldisks[i].dev, fldisks[i].devno[0], LUN_DIRECT,0); exit(rc); } if (1 == cmd) { //IO on a single PLUN break; } } rc = wait4all(); return rc; }
// 7.1.218 : Pass context token to different process & do REUSE int test_attach_reuse_diff_proc() { int rc=0; int nDisk; struct flash_disk cfDisk[2]; int cstat; struct ctx myctx; struct ctx *p_ctx = &myctx; pid = getpid(); nDisk = get_flash_disks(cfDisk, FDISKS_SAME_ADPTR); if (nDisk < 2) { fprintf(stderr,"Failed to find 2 flash disks from same adapter..\n"); return -1; } // sanity check for AIX! //#ifdef _AIX // if ( cfDisk[0].devno != cfDisk[1].devno ) return 1; //#endif rc = ctx_init2(p_ctx, cfDisk[0].dev, DK_AF_ASSIGN_AFU, cfDisk[0].devno[0]); CHECK_RC(rc, "p_ctx Context init failed"); rc = fork(); if ( rc == -1 ) CHECK_RC(1, "fork() failed"); // child process if ( rc == 0 ) { pid = getpid(); #ifdef _AIX rc = ctx_init2(p_ctx, cfDisk[1].dev, DK_AF_REUSE_CTX, cfDisk[0].devno[0]); if ( 0 == rc ) CHECK_RC_EXIT(1, "Context init with DK_AF_REUSE_CTX did not fail"); #else rc = ctx_init2(p_ctx, cfDisk[1].dev, DK_CXLFLASH_ATTACH_REUSE_CONTEXT, cfDisk[0].devno[0]); if ( 0 == rc ) CHECK_RC_EXIT(1, "Context init with DK_CXLFLASH_ATTACH_REUSE_CONTEXT did not fail"); #endif exit(0); } else { // Probe child's exit status. if ( wait(&cstat) == -1 ) CHECK_RC(1, "Failed while wait() for child"); // We expect child to exit itself if (WIFEXITED(cstat)) { // We expect child to exit with rc 0 only ! if ( WEXITSTATUS(cstat) != 0 ) rc=1; else rc=0; } } cleanup(p_ctx, -1); return rc; }
int ioctl_7_1_196() { int rc,i,j; struct ctx myctx[21],myctx_1, myctx_2; struct ctx *p_ctx[21],*p_ctx_1,*p_ctx_2; __u64 stride=0x1000,st_lba=0; pthread_t thread[20]; struct flash_disk disks[MAX_FDISK]; char disk1[30]; char disk2[30]; int cfdisk = MAX_FDISK; pid = getpid(); cfdisk = get_flash_disks(disks, FDISKS_SAME_ADPTR); //need to check the number of disks if (cfdisk < 2) { fprintf(stderr,"Must have 2 flash disks..\n"); TESTCASE_SKIP("Need disk from same adapter and each disk multipathed"); return 0; } strcpy(disk1,disks[0].dev); strcpy(disk2,disks[1].dev); // creating first context for (i=0;i<21;i++) { p_ctx[i]=&myctx[i]; } p_ctx_1=&myctx_1; p_ctx_2=&myctx_2; debug("1ST PROCEDURE\n"); // using p_ctx[[0] for LUN direct for firect disk /* rc = ctx_init2(p_ctx[0], disks[0].dev, DK_AF_ASSIGN_AFU, disks[0].devno[0]); pthread_create(&thread[0], NULL, ctx_rrq_rx, p_ctx[0]); */ /* rc = create_resource(p_ctx[0], 0, DK_UDF_ASSIGN_PATH, LUN_DIRECT); CHECK_RC(rc, "create LUN_DIRECT failed"); */ // creating another 19 context LUN VIRTUAL for ( i=2;i<21;i++) { sleep(2); rc = ctx_init2(p_ctx[i], disks[1].dev, DK_AF_ASSIGN_AFU, disks[1].devno[0]); rc=create_resource(p_ctx[i], p_ctx[i]->chunk_size, DK_UVF_ASSIGN_PATH, LUN_VIRTUAL); } // do context reuse for direct LUN strcpy(p_ctx[0]->dev,disks[0].dev); strcpy(p_ctx[1]->dev,disks[1].dev); p_ctx[0]->fd = open_dev(disks[0].dev, O_RDWR); if (p_ctx[0]->fd < 0) { fprintf(stderr, "open() failed: device %s, errno %d\n", disks[0].dev, errno); g_error = -1; return -1; } p_ctx[1]->fd = open_dev(disks[1].dev, O_RDWR); //Hoping to open second disk if (p_ctx[1]->fd < 0) { fprintf(stderr, "open() failed: device %s, errno %d\n", disks[1].dev, errno); g_error = -1; } #ifdef _AIX rc = ioctl_dk_capi_query_path(p_ctx[0]); CHECK_RC(rc, "DK_CAPI_QUERY_PATH failed"); #else //TBD for linux #endif p_ctx[0]->work.num_interrupts = p_ctx[1]->work.num_interrupts = 4; rc=ioctl_dk_capi_attach_reuse(p_ctx[0],p_ctx[1],LUN_DIRECT); // CHECK_RC(rc, "DK_CAPI_ATTACH with reuse flag failed"); if ( rc != 0 ) { fprintf(stderr,"LUN DIRECT got attached to new disk with VLUN, should have succeeded"); return rc; } // initiate I/O on all the LUNs for (i=2;i<21;i++) { pthread_create(&thread[i], NULL, ctx_rrq_rx, p_ctx[i]); rc = do_io(p_ctx[i], stride); } if ( rc != 0 ) { fprintf(stderr,"io on some LUN failed"); return rc; } /* using a goto-label removes the compile warning (-O3 issue) */ i=2; for_loop: pthread_cancel(thread[i]); close_res(p_ctx[i]); if (++i < 21) {goto for_loop;} ctx_close(p_ctx[2]); debug("2nd PROCEDURE\n"); // procedure 2 of the same case debug("%d: ........Phase 1 done.. Starting 2nd Phase........\n",getpid()); memset(p_ctx_1, 0, sizeof(struct ctx)); memset(p_ctx_2, 0, sizeof(struct ctx)); // open the first flash disk in write mode and create a DIRECT LUN // restoring from backup strcpy(disks[0].dev,disk1); p_ctx_1->fd = open_dev(disks[0].dev, O_WRONLY); if (p_ctx_1->fd < 0) { fprintf(stderr, "open() failed: device %s, errno %d\n", disks[0].dev, errno); return -1; } rc = ctx_init2(p_ctx_1, disks[0].dev, DK_AF_ASSIGN_AFU, disks[0].devno[0]); pthread_create(&thread[0], NULL, ctx_rrq_rx, p_ctx_1); CHECK_RC(rc, "create context failed"); rc = create_resource(p_ctx_1, 0, DK_UDF_ASSIGN_PATH, LUN_DIRECT); CHECK_RC(rc, "create LUN_DIRECT failed"); // open the same flash disk in read mode again. p_ctx_2->fd = open_dev(disks[0].dev, O_RDONLY); if (p_ctx_2->fd < 0) { fprintf(stderr, "open() failed: device %s, errno %d\n", disks[0].dev, errno); return -1; } rc = ctx_init2(p_ctx_2, disks[0].dev, DK_AF_ASSIGN_AFU, disks[0].devno[0]); pthread_create(&thread[1], NULL, ctx_rrq_rx, p_ctx_2); CHECK_RC(rc, "create context failed"); rc = create_resource(p_ctx_2, 0, DK_UDF_ASSIGN_PATH, LUN_DIRECT); CHECK_RC(rc, "create LUN_DIRECT failed"); // now write to the disk and then read for (st_lba = 0; st_lba <= p_ctx_1->last_lba; st_lba += (NUM_CMDS*stride)) { rc = send_write(p_ctx_1, st_lba, stride, pid); CHECK_RC(rc, "send_write failed"); rc = send_read(p_ctx_2, st_lba, stride); CHECK_RC(rc, "send_read failed"); /*if (rc !=0 ) { rc = rw_cmp_buf(p_ctx_1, st_lba); if (rc != 0) { fprintf(stderr,"buf cmp failed for lba 0x%lX,rc =%d\n",st_lba,rc); break; } }*/ } if ( rc != 0 ) return rc; for (i=0;i<2;i++) { pthread_cancel(thread[i]); } //close_res(p_ctx_1); ctx_close(p_ctx_1); //close_res(p_ctx_2); ctx_close(p_ctx_2); debug("3rd PROCEDURE\n"); debug("%d: ........Phase 2 done.. Starting 3rd Phase........\n",getpid()); // case 3 of the same case // creating multiple process for LUN_DIRECT creation. for (j=0;j<long_run;j++) { for (i=0; i<20;i++) { if ( 0 == fork()) { rc = ctx_init(p_ctx[i]); CHECK_RC_EXIT(rc, "Context init failed"); // CHECK_RC(rc, "Context init failed"); //thread to handle AFU interrupt & events rc = create_resource(p_ctx[i], 0, DK_UDF_ASSIGN_PATH , LUN_DIRECT); CHECK_RC_EXIT(rc, "create LUN_DIRECT failed"); // do io on context pthread_create(&thread[i], NULL, ctx_rrq_rx, p_ctx[i]); stride=0x1000; sleep(2); //do_io(p_ctx[i], stride); pthread_cancel(thread[i]); close_res(p_ctx[i]); exit(rc); } } wait4all(); } return 0; }