int max_ctx_on_plun(int cmd)
{
    int i;
    int rc = 0;
    struct ctx myctx;
    struct ctx *p_ctx=&myctx;
    pid = getpid();
    pthread_t thread;
    int max_p = MAX_OPENS;
    for (i=0; i<max_p;i++)
    {
        if (0==fork())
        {
            //child process
            pid = getpid();
            debug("%d: ......process %d created...\n",pid,i);
            memset(p_ctx, 0, sizeof(myctx));
            strcpy(p_ctx->dev, cflash_path);
            if ((p_ctx->fd = open_dev(p_ctx->dev, O_RDWR)) < 0)
            {
                fprintf(stderr,"open failed %s, errno %d\n",cflash_path, errno);
                exit(rc);
            }
#ifdef _AIX
            rc |= ioctl_dk_capi_query_path(p_ctx);
            rc|=ctx_init_internal(p_ctx, 0, p_ctx->devno);
#else
            rc|=ctx_init_internal(p_ctx, 0x2, p_ctx->devno);
#endif
            if (2 == cmd)
                rc |=create_resource(p_ctx,0,0,LUN_VIRTUAL);
            if (3 == cmd)
                rc |=create_resource(p_ctx,0,0,LUN_DIRECT);
            if (4 == cmd)
            {
                //do io all vluns created on path_id_mask
                pthread_create(&thread, NULL,ctx_rrq_rx,p_ctx);
                rc |= create_resource(p_ctx,p_ctx->chunk_size,0,LUN_VIRTUAL);
                rc |= do_io(p_ctx,0x10);

                pthread_cancel(thread);
            }
            sleep(10); //lets all context get created
            if ( 1 != cmd )
                rc|=close_res(p_ctx);
            rc|=ctx_close(p_ctx);
            debug("%d:.exiting with rc=%d\n",pid,rc);
            exit(rc);
        }
    }
    rc=wait4all();
    return rc;
}
Esempio n. 2
0
int test_fc_port_reset_vlun()
{
    int rc;
    struct ctx myctx;
    struct ctx *p_ctx = &myctx;
    pthread_t thread;
    int ioCounter=0;
    __u64 nlba;
    __u64 stride=0x1;

    pid = getpid();
#ifdef _AIX
    memset(p_ctx, 0, sizeof(myctx));
    strcpy(p_ctx->dev, cflash_path);
    if ((p_ctx->fd =open_dev(p_ctx->dev, O_RDWR)) < 0)
    {
        fprintf(stderr,"open %s failed, errno=%d\n",p_ctx->dev,errno);
        return -1;
    }
    rc = ioctl_dk_capi_query_path(p_ctx);
    CHECK_RC(rc,"dk_capi_query_path failed..\n");
    rc = ctx_init_internal(p_ctx, 0,p_ctx->devno);
#else
    rc = ctx_init(p_ctx);
#endif
    CHECK_RC(rc, "Context init failed");

    //thread to handle AFU interrupt & events
    pthread_create(&thread, NULL, ctx_rrq_rx, p_ctx);

    nlba = 1 * (p_ctx->chunk_size);
    rc = create_resource(p_ctx, nlba, 0, LUN_VIRTUAL);
    CHECK_RC(rc, "create LUN_VIRTUAL failed");
    rc = compare_size(p_ctx->last_lba, nlba-1);
    CHECK_RC(rc, "failed compare_size");

    debug("-- Going to start IO.Please do chportfc -reset <pnum> at texan --\n");

    debug("rc=%d,g_error=%d\n",rc,g_error);
    do
    {
        rc = do_io(p_ctx, stride);
        if (rc !=0 )
        {
            debug("rc=%d,ioCounter=%d,IO failed..... \n",rc,ioCounter);
            if ( ioCounter==1 )
            {
                debug("rc=%d, Going to verify.... \n",rc);

                p_ctx->flags=DK_VF_LUN_RESET;
#ifdef _AIX
                p_ctx->hint = DK_HINT_SENSE;
#else
                p_ctx->hint = DK_CXLFLASH_VERIFY_HINT_SENSE;
#endif
                rc = ioctl_dk_capi_verify(p_ctx);
                CHECK_RC(rc, "ioctl_dk_capi_verify failed\n");
            }
            else
            { if (ioCounter > 1)
                {
                    rc=-1; // IO failed third time
                    break;
                }
            }

        }
        else
        {
            debug("rc=%d,IO succeeded \n",rc);
            g_error=0;
        }

        ioCounter++;
        rc|=g_error;
        sleep(3);

    } while ( rc !=0);

    debug("rc=%d,g_error=%d\n",rc,g_error);

    if ( ioCounter <= 1)
    {
        debug("WARNING: Test case not excuted properly... Please rerun\n");
        rc =255;
    }

    pthread_cancel(thread);
    close_res(p_ctx);
    ctx_close(p_ctx);
    rc |= g_error;
    return rc;
}
//int create_res_hndl_afu_reset(char *dev, dev64_t devno, __u64 chunk)
int create_res_hndl_afu_reset(bool do_recover, bool last)
{
    int rc;
    struct ctx my_ctx;
    struct ctx *p_ctx = &my_ctx;
    //int i;
    pthread_t thread;
    __u64 chunk = 0x1;
    __u64 stride= 0x1;
    int msgid;
    struct mymsgbuf msg_buf;
    pthread_t ioThreadId;
    do_io_thread_arg_t ioThreadData;
    do_io_thread_arg_t * p_ioThreadData=&ioThreadData;
    // we have to export "NO_IO; if we want to avoid IO
    char * noIOP   = getenv("NO_IO");

    pid = getpid();
#ifdef _AIX
    memset(p_ctx,0,sizeof(my_ctx));
    strcpy(p_ctx->dev,cflash_path);
    if ((p_ctx->fd = open_dev(p_ctx->dev, O_RDWR)) < 0)
    {
        fprintf(stderr,"open failed %s, errno %d\n",p_ctx->dev, errno);
        return -1;
    }
    rc = ioctl_dk_capi_query_path(p_ctx);
    CHECK_RC(rc, "ioctl_dk_capi_query_path failed...\n");
    rc = ctx_init_internal(p_ctx, 0, p_ctx->devno);
#else
    rc = ctx_init(p_ctx);
#endif
    CHECK_RC(rc, "Context init failed");

    //thread to handle AFU interrupt & events
    if ( noIOP == NULL )
        pthread_create(&thread, NULL, ctx_rrq_rx, p_ctx);

    //create 0 vlun size & later call resize ioctl
    rc = create_resource(p_ctx, chunk * (p_ctx->chunk_size),
                         0, LUN_VIRTUAL);
    CHECK_RC(rc, "create LUN_VIRTUAL failed");

    //last new process send message to waiting process
    //that new ctx created now you can try to reattach
    msgid = msgget(key, IPC_CREAT | 0666);
    if (msgid < 0 )
    {
        fprintf(stderr, "%d: msgget() failed before msgsnd()\n", pid);
        return -1;
    }
    memset(&msg_buf, 0, sizeof(struct mymsgbuf));
    if (last)
    {
        goto end;
    }
    if ( noIOP == NULL )
    {
        p_ioThreadData->p_ctx=p_ctx;
        p_ioThreadData->stride=stride;
        p_ioThreadData->loopCount=0x100000; // Need this to go on 10 secs
        debug("%d: things look good, doing IO...\n",pid);
        rc =pthread_create(&ioThreadId,NULL, do_io_thread, (void *)p_ioThreadData);
        CHECK_RC(rc, "do_io_thread() pthread_create failed");
    }
#ifdef _AIX
    rc = do_eeh(p_ctx);
#else
    rc = do_poll_eeh(p_ctx);
#endif
    g_error=0; //reset any prev error might caught while EEH
    if ( noIOP == NULL )
    {
        pthread_join(ioThreadId, NULL);
    }
#ifndef _AIX //for linux
    if ( noIOP == NULL )
        pthread_cancel(thread);
#endif

    //We here after EEH done
    if (do_recover)
    {
        //do if recover true
        debug("%d: woow EEH is done recovering...\n",pid);
        rc = ioctl_dk_capi_recover_ctx(p_ctx);
        CHECK_RC(rc, "ctx reattached failed");
        msg_buf.mtype =2;
        strcpy(msg_buf.mtext, "K");
        if (msgsnd(msgid, &msg_buf, 2, IPC_NOWAIT) < 0)
        {
            fprintf(stderr, "%d: msgsnd failed\n", pid);
            return -1;
        }
#ifdef _AIX
        if (p_ctx->return_flags != DK_RF_REATTACHED)
            CHECK_RC(1, "recover ctx, expected DK_RF_REATTACHED");
        p_ctx->flags = DK_VF_HC_TUR;
        p_ctx->hint = DK_HINT_SENSE;
#endif
        fflush(stdout);
        ctx_reinit(p_ctx);
#ifdef _AIX
        p_ctx->hint=DK_HINT_SENSE;
#else
        p_ctx->hint=DK_CXLFLASH_VERIFY_HINT_SENSE;
        // if dummy_sense_flag is set;
        // a dummy sense data will be copied into ioctl input
        p_ctx->dummy_sense_flag=1; // if dummy_sense_flag is set;
#endif
        rc = ioctl_dk_capi_verify(p_ctx);
        CHECK_RC(rc, "ioctl_dk_capi_verify failed");
#ifndef _AIX //for linux
        pthread_create(&thread, NULL, ctx_rrq_rx, p_ctx);
#endif
    }
    else
    {
        //last one is
        /*msgid = msgget(key, IPC_CREAT | 0666);
           if(msgid < 0 ){
                   fprintf(stderr, "%d: msgget() failed before msgrcv()\n", pid);
                   return -1;
           }
           debug("%d: Going to wait at msgrcv()..\n", pid);
           fflush(stdout);
           if(msgrcv(msgid, &msg_buf, 2, 1, 0) < 0) {
                   fprintf(stderr, "%d: msgrcv failed with errno %d\n", pid, errno);
                   return -1;
           }

           debug("%d: Got out of msgrcv()..EEH is done, Try to recover....\n",pid);
         */
        //as per today(9/28/2015) discussion with Sanket that
        //new attach will fail until holding context not exited
        //hope same apply for Linux as well
        return 100;
        /*rc = ioctl_dk_capi_recover_ctx(p_ctx);
           if(rc) return 100; //this to make sure recover failed
           else {
                   fprintf(stderr,"%d:com'on recover should fail here...\n",pid);
                   return 1; // we don't want to try IO anyway
           }*/
    }

end:
    if ( noIOP == NULL )
    {
        stride=0x1;
        rc = do_io(p_ctx, stride);
        CHECK_RC(rc, "IO failed after EEH/recover");
    }
    if ( noIOP == NULL )
        pthread_cancel(thread);
    sleep(1);
    fflush(stdout);
    sleep(5); // additional time to be safe !
    rc=close_res(p_ctx);

    sleep(5); // Don't let child exit to keep max ctx alive
    rc |= ctx_close(p_ctx);
    CHECK_RC(rc,"ctx close or close_res failed\n");
    return rc;
}
int max_ctx_max_res(int cmd)
{
    int rc;
    int i;
    struct ctx myctx;
    struct ctx *p_ctx=&myctx;
    int max_p = MAX_OPENS; // we can change MAX_OPEN Value in cflash_tests.h
    memset(p_ctx, 0, sizeof(struct ctx));
    __u64 chunk = 0;
    __u64 lba;
    MAX_RES_HANDLE=get_max_res_hndl_by_capacity(cflash_path);
    if (MAX_RES_HANDLE <= 0)
    {
        fprintf(stderr,"Unable to run max_ctx_max_res.. refere prior error..\n");
        return -1;
    }
    strcpy(p_ctx->dev, cflash_path);
#ifdef _AIX
    p_ctx->fd =open_dev(p_ctx->dev, O_RDWR);
    if (p_ctx->fd <  0)
    {
        fprintf(stderr,"%s open failed...\n",p_ctx->dev);
        return -1;
    }
    rc = ioctl_dk_capi_query_path(p_ctx);
    CHECK_RC(rc, "query ioctl failed");
    close(p_ctx->fd);
#endif
    uint64_t chunk_size;
    if (2 == cmd)
    {
        lba = get_disk_last_lba(p_ctx->dev, p_ctx->devno, &chunk_size);
        if (lba == 0)
        {
            fprintf(stderr, "Failed to get last_lba of %s\n", p_ctx->dev);
            return -1;
        }
        chunk =  (lba+1)/chunk_size;
        //chunks per context( each context will 16 VLUNS same size)
        chunk = chunk/(max_p * MAX_RES_HANDLE);
        if ( chunk == 0 )
        {
            fprintf(stderr,"chunk-> 0X%"PRIX64" should >= max_p * MAX_RES_HANDLE=>%d\n",
                    chunk,(max_p * MAX_RES_HANDLE));
            return -1;
        }
        chunkRemain = chunk%(max_p * MAX_RES_HANDLE);
    }

    for (i = 0; i< max_p; i++)
    {
        if (0 == fork())
        {
            //child process
            usleep(10000);
            if (2 == cmd)
            {
                if (i == max_p-1 )
                {
                    // this is the last context
                    imLastContext=1;
                }
                rc = create_ctx_process(p_ctx->dev, p_ctx->devno,chunk);
            }
            else
            {
                rc = create_ctx_process(p_ctx->dev, p_ctx->devno,1);
            }
            debug("%d: exiting with rc=%d\n",getpid(), rc);
            exit(rc);
        }
    }
    rc = wait4all();
    return rc;
}
Esempio n. 5
0
// 7.1.202 : Try to send a ctx_id in some ioctl before attach
// (i.e. when no ctx is established). & some more scenarios
int test_ioctl_spio_errcase()
{
    int rc;
    int itr, type;
    struct ctx myctx;
    struct ctx *p_ctx = &myctx;
    char *fvt_dev;
    pthread_t threadId;
    __u64 nlba; // stride; //stride not used

    pid = getpid();

    memset((void *)p_ctx, 0, sizeof(struct ctx));

    // Case1
    // ---------- IOCTL error cases w/o context : Start ----------
    fvt_dev = getenv("FVT_DEV");
    if (NULL == fvt_dev)
    {
        fprintf(stderr, "FVT_DEV ENV var NOT set, Please set...\n");
        return -1;
    }

    strcpy(p_ctx->dev, fvt_dev);

    //open CAPI Flash disk device
    debug("Going to open CAPI Flash disk \n");
    p_ctx->fd = open_dev(fvt_dev, O_RDWR);
    if (p_ctx->fd < 0) CHECK_RC(1, "capi device open() failed");

#ifdef _AIX
    // Get the devno. : only needed for AIX
    rc = ioctl_dk_capi_query_path(p_ctx);
    CHECK_RC(rc, "query path ioctl failed");

#endif

#ifdef _AIX
    p_ctx->work.num_interrupts = 5; // use num_interrupts from AFU desc
#else
    p_ctx->work.num_interrupts = 4; // use num_interrupts from AFU desc
#endif /*_AIX*/

    p_ctx->context_id = 0x1;

    rc = ioctl_dk_capi_detach(p_ctx);
    if ( 22 != rc ) CHECK_RC(1, "context detach ioctl did not fail");

    p_ctx->flags = DK_UDF_ASSIGN_PATH;

    rc = ioctl_dk_capi_udirect(p_ctx);
    if ( 22 != rc ) CHECK_RC(1, "pLun creation did not fail");

    g_error=0; // reset-ing the g_error
    close(p_ctx->fd);

    debug("Done. Close the fd \n");
    // ---------- IOCTL error cases w/o context : End ----------

    // Test for both pLun & vLun !
    for (itr=0; itr<2; itr++)
    {
        debug("\n\n\n%d:-------- Start Itr# %d -------\n", pid, itr);
        // Test Case2 & Case3
        for (type=0; type<2; type++)
        {
            debug("\n%d:-------- Start test type# %d -------\n", pid, type);
            // ctx_init with default flash disk & devno
            rc = ctx_init(p_ctx);
            CHECK_RC(rc, "Context init failed");

            // thread to handle AFU interrupt & events
            rc = pthread_create(&threadId, NULL, ctx_rrq_rx, p_ctx);
            CHECK_RC(rc, "pthread_create failed");

            if ( 0 == itr )
            {
                // create plun
                rc = create_resource(p_ctx, 0, DK_UDF_ASSIGN_PATH, LUN_DIRECT);
                CHECK_RC(rc, "create LUN_DIRECT failed");
            }
            else
            {
                nlba = p_ctx->chunk_size;
                // create vlun
                rc = create_resource(p_ctx,nlba, DK_UVF_ALL_PATHS, LUN_VIRTUAL);
                CHECK_RC(rc, "create LUN_VIRTUAL failed");
            }

            if ( 0 == type )
            {
                // -------- Case2: IO error cases after context detach -------
                pthread_cancel(threadId);
                rc = ioctl_dk_capi_detach(p_ctx);
                CHECK_RC(rc, "detach ioctl failed");
            }
            else
            {
                // -------- Case3: IO error cases after fd close -------
                pthread_cancel(threadId);
                rc = close(p_ctx->fd);
                CHECK_RC(rc, "close(fd) failed");
                debug("%d: close(p_ctx->fd) i.e. close(%d): done !\n", pid, p_ctx->fd);
            }

            // Reset rc if we reach this point.
            rc = 0;
            g_error=0;
            debug("rc %d, g_error =%d, errno =%d\n" , rc , g_error, errno );
            //open CAPI Flash disk device again for clean using ioctls
            p_ctx->fd = open_dev(fvt_dev, O_RDWR);
            debug("After disk reopned -- rc %d, g_error =%d, errno =%d\n" , rc , g_error, errno );
            if (p_ctx->fd < 0) CHECK_RC(1, "capi device open() failed");
            debug("%d: disk re-opened, new fd: %d\n", pid, p_ctx->fd);
            cleanup(p_ctx, -1);
        }
    }

    return 0;
}
Esempio n. 6
0
// 7.1.194 : Test DK_CAPI_QUERY_PATH & DK_CAPI_ATTACH ioctl for FCP disk
int test_ioctl_fcp()
{
    int rc=0;
    struct ctx myctx;
    struct ctx *p_ctx = &myctx;

    char fc_dev[MC_PATHLEN];
    dev64_t fc_devno;

    pid = getpid();

    // Get the FC disk from env.
    rc = get_nonflash_disk(&fc_dev[0], &fc_devno);
    CHECK_RC(rc, "get_nonflash_disk() failed to get FC disk");

    // Open fc disk
    p_ctx->fd = open(fc_dev, O_RDWR);
    if (p_ctx->fd < 0)
    {
        fprintf(stderr, "open() failed: device %s, errno %d\n", fc_dev, errno);
        return -1;
    }

#ifdef _AIX

    // query path ioctl isn't supported on linux
    // Call query path ioctl
    rc = ioctl_dk_capi_query_path(p_ctx);
    if ( 0 == rc )
        CHECK_RC(1, "ioctl_dk_capi_query_path didn't fail");

    // Verify return values after ioctl
    // TBD: return_path_count need to be added to ctx.
    if ( p_ctx->return_path_count != 0 ||
         p_ctx->return_flags != DK_RF_IOCTL_FAILED )
        CHECK_RC(1, "returned_path_count/return_flags is incorrect..");

#endif /*_AIX */

    // Prepare for attach ioctl
    p_ctx->flags = DK_AF_ASSIGN_AFU;
    p_ctx->work.num_interrupts = 4; // use num_interrupts from AFU desc
#ifdef _AIX
    p_ctx->devno = fc_devno;
#endif /*_AIX */

    // Clear the previous RF before subsequent ioctl
    p_ctx->return_flags=0;

    strcpy(p_ctx->dev, fc_dev);

    //do context attach
    rc = ioctl_dk_capi_attach(p_ctx);
    if ( 0 == rc )
        CHECK_RC(1, "ioctl_dk_capi_attach didn't fail");

    // Verify return values after ioctl
    if ( p_ctx->return_flags != DK_RF_IOCTL_FAILED )
        CHECK_RC(1, "return_flags is incorrect..");

    // If we reach here, we return success.
    return 0;
}
Esempio n. 7
0
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;

}