// 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 do_attach_detach(char *dev, dev64_t devno, __u16 lun_type)
{
    int rc;
    struct ctx myctx;
    struct ctx *p_ctx = &myctx;
    __u64 chunk = 20;
    __u64 nlba;
    int count = 20;
    char *str = getenv("LONG_RUN");
    if (str != NULL)
    {
        count = 100000;
        printf("LONG_RUN enabled...loop=%d\n",count);
        fflush(stdout);
    }
    pid = getpid();

    while (count-- >0)
    {
        rc = ctx_init2(p_ctx, dev, DK_AF_ASSIGN_AFU, devno);
        CHECK_RC(rc, "Context init failed");
        if (LUN_VIRTUAL == lun_type)
        {
            chunk = rand()%16;
            //create 0 vlun size & later call resize ioctl
            rc = create_resource(p_ctx, chunk, DK_UVF_ALL_PATHS, lun_type);
            CHECK_RC(rc, "create LUN_VIRTUAL failed");
            chunk = rand()%32;
            nlba = chunk * p_ctx->chunk_size;
            rc = vlun_resize(p_ctx, nlba);
            CHECK_RC(rc, "vlun_resize failed");
        }
        else
        {
            rc = create_resource(p_ctx,0, DK_UDF_ASSIGN_PATH, lun_type);
            CHECK_RC(rc, "create LUN_DIRECT failed");
        }
        close_res(p_ctx);
        ctx_close(p_ctx);
        if (count%500 == 0)
            printf("%d: loop remains....\n",count);
        fflush(stdout);
    }
    return 0;
}
int create_ctx_process(char *dev, dev64_t devno, __u64 chunk)
{
    int rc;
    struct ctx my_ctx;
    struct ctx *p_ctx = &my_ctx;
    g_error=0;
    pid = getpid();
    pthread_t threads[MAX_RES_HANDLE];
    pthread_t intr_thread;
    //__u64 flags;
    int i;

    rc = ctx_init2(p_ctx, dev, DK_AF_ASSIGN_AFU, devno);
    CHECK_RC(rc, "Context init failed");
    // interrupt handler per context
    rc = pthread_create(&intr_thread, NULL, ctx_rrq_rx, p_ctx);

    p_ctx ->lun_size = chunk * p_ctx->chunk_size;
    for (i = 0; i <MAX_RES_HANDLE; i++)
    {
        if ( MAX_RES_HANDLE == i+1 && imLastContext == 1 )
        { // this is last resource of last context
            debug("%d:create_ctx_process: last res ==> %d of last contxt \n", pid,i+1);
            p_ctx ->lun_size = ( chunk + chunkRemain )*p_ctx->chunk_size;
        }
        rc = pthread_create(&threads[i], NULL, res_thread, p_ctx);
        CHECK_RC(rc, "pthread_create failed");
    }
    //wait all threads to get complete
    for (i = 0; i <MAX_RES_HANDLE; i++)
    {
        pthread_join(threads[i], NULL);
    }

    pthread_cancel(intr_thread);

    rc = g_error;
    g_error = 0;
    return rc;
}
int test_spio_lun(char *dev, dev64_t devno,
                   __u16 lun_type, __u64 chunk)
{
    int rc;
    struct ctx myctx;
    struct ctx *p_ctx = &myctx;
    pthread_t thread;
    int loop=5;
    int i=0;

    __u64 nlba = 0;
    __u64 stride= 0x1000;

    pid = getpid();

    rc = ctx_init2(p_ctx, dev, DK_AF_ASSIGN_AFU, devno);
    CHECK_RC(rc, "Context init failed");

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

    if ( LUN_DIRECT == lun_type)
    {
        rc = create_resource(p_ctx, 0, DK_UDF_ASSIGN_PATH, LUN_DIRECT);
        CHECK_RC(rc, "create LUN_DIRECT failed");
        if (long_run_enable) stride=0x100;
        rc = do_io(p_ctx, stride);
    }
    else
    {
        rc = create_resource(p_ctx, nlba,
                             DK_UVF_ALL_PATHS, LUN_VIRTUAL);
        CHECK_RC(rc, "create LUN_VIRTUAL failed");
        nlba = chunk * p_ctx->chunk_size;
        rc = vlun_resize(p_ctx, nlba);
        if (rc == 28)
        {
            fprintf(stderr, "%d:Requested was more..try with half now...\n",pid);
            nlba = nlba/2;
            rc = vlun_resize(p_ctx, nlba);
            if (rc == 28)
            {
                fprintf(stderr, "%d: No space left.. terminate this context..\n",pid);
                return 0;
            }
        }
        CHECK_RC(rc, "vlun_resize failed");
        if (long_run_enable)
        {
            stride=0x1;
            //loop=20;
        }
        while (i++<loop)
        {
            if (long_run_enable)
                printf("%d:IO loop %d(%d) started....\n",pid,i,loop);
            rc = do_io(p_ctx, stride);
            if (rc) break;
        }
    }

    usleep(1000); //let all process do io
    pthread_cancel(thread);
    close_res(p_ctx);
    ctx_close(p_ctx);
    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;
}
Beispiel #6
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;

}