static int iscsi_open(BlockDriverState *bs, const char *filename, int flags)

{

    IscsiLun *iscsilun = bs->opaque;

    struct iscsi_context *iscsi = NULL;

    struct iscsi_url *iscsi_url = NULL;

    struct IscsiTask task;

    char *initiator_name = NULL;

    int ret;



    if ((BDRV_SECTOR_SIZE % 512) != 0) {

        error_report("iSCSI: Invalid BDRV_SECTOR_SIZE. "

                     "BDRV_SECTOR_SIZE(%lld) is not a multiple "

                     "of 512", BDRV_SECTOR_SIZE);

        return -EINVAL;

    }



    iscsi_url = iscsi_parse_full_url(iscsi, filename);

    if (iscsi_url == NULL) {

        error_report("Failed to parse URL : %s %s", filename,

                     iscsi_get_error(iscsi));

        ret = -EINVAL;

        goto out;

    }



    memset(iscsilun, 0, sizeof(IscsiLun));



    initiator_name = parse_initiator_name(iscsi_url->target);



    iscsi = iscsi_create_context(initiator_name);

    if (iscsi == NULL) {

        error_report("iSCSI: Failed to create iSCSI context.");

        ret = -ENOMEM;

        goto out;

    }



    if (iscsi_set_targetname(iscsi, iscsi_url->target)) {

        error_report("iSCSI: Failed to set target name.");

        ret = -EINVAL;

        goto out;

    }



    if (iscsi_url->user != NULL) {

        ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user,

                                              iscsi_url->passwd);

        if (ret != 0) {

            error_report("Failed to set initiator username and password");

            ret = -EINVAL;

            goto out;

        }

    }



    /* check if we got CHAP username/password via the options */

    if (parse_chap(iscsi, iscsi_url->target) != 0) {

        error_report("iSCSI: Failed to set CHAP user/password");

        ret = -EINVAL;

        goto out;

    }



    if (iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL) != 0) {

        error_report("iSCSI: Failed to set session type to normal.");

        ret = -EINVAL;

        goto out;

    }



    iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);



    /* check if we got HEADER_DIGEST via the options */

    parse_header_digest(iscsi, iscsi_url->target);



    task.iscsilun = iscsilun;

    task.status = 0;

    task.complete = 0;

    task.bs = bs;



    iscsilun->iscsi = iscsi;

    iscsilun->lun   = iscsi_url->lun;



    if (iscsi_full_connect_async(iscsi, iscsi_url->portal, iscsi_url->lun,

                                 iscsi_connect_cb, &task)

        != 0) {

        error_report("iSCSI: Failed to start async connect.");

        ret = -EINVAL;

        goto out;

    }



    while (!task.complete) {

        iscsi_set_events(iscsilun);

        qemu_aio_wait();

    }

    if (task.status != 0) {

        error_report("iSCSI: Failed to connect to LUN : %s",

                     iscsi_get_error(iscsi));

        ret = -EINVAL;

        goto out;

    }



    /* Medium changer or tape. We dont have any emulation for this so this must

     * be sg ioctl compatible. We force it to be sg, otherwise qemu will try

     * to read from the device to guess the image format.

     */

    if (iscsilun->type == TYPE_MEDIUM_CHANGER ||

        iscsilun->type == TYPE_TAPE) {

        bs->sg = 1;

    }



    ret = 0;



out:

    if (initiator_name != NULL) {

        g_free(initiator_name);

    }

    if (iscsi_url != NULL) {

        iscsi_destroy_url(iscsi_url);

    }



    if (ret) {

        if (iscsi != NULL) {

            iscsi_destroy_context(iscsi);

        }

        memset(iscsilun, 0, sizeof(IscsiLun));

    }

    return ret;

}

static int iscsi_open(BlockDriverState *bs, const char *filename, int flags)

{

    IscsiLun *iscsilun = bs->opaque;

    struct iscsi_context *iscsi = NULL;

    struct iscsi_url *iscsi_url = NULL;

    struct IscsiTask task;

    char *initiator_name = NULL;

    int ret;



    if ((BDRV_SECTOR_SIZE % 512) != 0) {

        error_report("iSCSI: Invalid BDRV_SECTOR_SIZE. "

                     "BDRV_SECTOR_SIZE(%lld) is not a multiple "

                     "of 512", BDRV_SECTOR_SIZE);

        return -EINVAL;

    }



    iscsi_url = iscsi_parse_full_url(iscsi, filename);

    if (iscsi_url == NULL) {

        error_report("Failed to parse URL : %s %s", filename,

                     iscsi_get_error(iscsi));

        ret = -EINVAL;

        goto out;

    }



    memset(iscsilun, 0, sizeof(IscsiLun));



    initiator_name = parse_initiator_name(iscsi_url->target);



    iscsi = iscsi_create_context(initiator_name);

    if (iscsi == NULL) {

        error_report("iSCSI: Failed to create iSCSI context.");

        ret = -ENOMEM;

        goto out;

    }



    if (iscsi_set_targetname(iscsi, iscsi_url->target)) {

        error_report("iSCSI: Failed to set target name.");

        ret = -EINVAL;

        goto out;

    }



    if (iscsi_url->user != NULL) {

        ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user,

                                              iscsi_url->passwd);

        if (ret != 0) {

            error_report("Failed to set initiator username and password");

            ret = -EINVAL;

            goto out;

        }

    }



    

    if (parse_chap(iscsi, iscsi_url->target) != 0) {

        error_report("iSCSI: Failed to set CHAP user/password");

        ret = -EINVAL;

        goto out;

    }



    if (iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL) != 0) {

        error_report("iSCSI: Failed to set session type to normal.");

        ret = -EINVAL;

        goto out;

    }



    iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);



    

    parse_header_digest(iscsi, iscsi_url->target);



    task.iscsilun = iscsilun;

    task.status = 0;

    task.complete = 0;

    task.bs = bs;



    iscsilun->iscsi = iscsi;

    iscsilun->lun   = iscsi_url->lun;



    if (iscsi_full_connect_async(iscsi, iscsi_url->portal, iscsi_url->lun,

                                 iscsi_connect_cb, &task)

        != 0) {

        error_report("iSCSI: Failed to start async connect.");

        ret = -EINVAL;

        goto out;

    }



    while (!task.complete) {

        iscsi_set_events(iscsilun);

        qemu_aio_wait();

    }

    if (task.status != 0) {

        error_report("iSCSI: Failed to connect to LUN : %s",

                     iscsi_get_error(iscsi));

        ret = -EINVAL;

        goto out;

    }



    







    if (iscsilun->type == TYPE_MEDIUM_CHANGER ||

        iscsilun->type == TYPE_TAPE) {

        bs->sg = 1;

    }



    ret = 0;



out:

    if (initiator_name != NULL) {

        g_free(initiator_name);

    }

    if (iscsi_url != NULL) {

        iscsi_destroy_url(iscsi_url);

    }



    if (ret) {

        if (iscsi != NULL) {

            iscsi_destroy_context(iscsi);

        }

        memset(iscsilun, 0, sizeof(IscsiLun));

    }

    return ret;

}

static int FUNC_0(BlockDriverState *VAR_0, const char *VAR_1, int VAR_2)

{

    IscsiLun *iscsilun = VAR_0->opaque;

    struct iscsi_context *VAR_3 = NULL;

    struct VAR_4 *VAR_4 = NULL;

    struct IscsiTask VAR_5;

    char *VAR_6 = NULL;

    int VAR_7;



    if ((BDRV_SECTOR_SIZE % 512) != 0) {

        error_report("iSCSI: Invalid BDRV_SECTOR_SIZE. "

                     "BDRV_SECTOR_SIZE(%lld) is not a multiple "

                     "of 512", BDRV_SECTOR_SIZE);

        return -EINVAL;

    }



    VAR_4 = iscsi_parse_full_url(VAR_3, VAR_1);

    if (VAR_4 == NULL) {

        error_report("Failed to parse URL : %s %s", VAR_1,

                     iscsi_get_error(VAR_3));

        VAR_7 = -EINVAL;

        goto out;

    }



    memset(iscsilun, 0, sizeof(IscsiLun));



    VAR_6 = parse_initiator_name(VAR_4->target);



    VAR_3 = iscsi_create_context(VAR_6);

    if (VAR_3 == NULL) {

        error_report("iSCSI: Failed to create iSCSI context.");

        VAR_7 = -ENOMEM;

        goto out;

    }



    if (iscsi_set_targetname(VAR_3, VAR_4->target)) {

        error_report("iSCSI: Failed to set target name.");

        VAR_7 = -EINVAL;

        goto out;

    }



    if (VAR_4->user != NULL) {

        VAR_7 = iscsi_set_initiator_username_pwd(VAR_3, VAR_4->user,

                                              VAR_4->passwd);

        if (VAR_7 != 0) {

            error_report("Failed to set initiator username and password");

            VAR_7 = -EINVAL;

            goto out;

        }

    }



    

    if (parse_chap(VAR_3, VAR_4->target) != 0) {

        error_report("iSCSI: Failed to set CHAP user/password");

        VAR_7 = -EINVAL;

        goto out;

    }



    if (iscsi_set_session_type(VAR_3, ISCSI_SESSION_NORMAL) != 0) {

        error_report("iSCSI: Failed to set session type to normal.");

        VAR_7 = -EINVAL;

        goto out;

    }



    iscsi_set_header_digest(VAR_3, ISCSI_HEADER_DIGEST_NONE_CRC32C);



    

    parse_header_digest(VAR_3, VAR_4->target);



    VAR_5.iscsilun = iscsilun;

    VAR_5.status = 0;

    VAR_5.complete = 0;

    VAR_5.VAR_0 = VAR_0;



    iscsilun->VAR_3 = VAR_3;

    iscsilun->lun   = VAR_4->lun;



    if (iscsi_full_connect_async(VAR_3, VAR_4->portal, VAR_4->lun,

                                 iscsi_connect_cb, &VAR_5)

        != 0) {

        error_report("iSCSI: Failed to start async connect.");

        VAR_7 = -EINVAL;

        goto out;

    }



    while (!VAR_5.complete) {

        iscsi_set_events(iscsilun);

        qemu_aio_wait();

    }

    if (VAR_5.status != 0) {

        error_report("iSCSI: Failed to connect to LUN : %s",

                     iscsi_get_error(VAR_3));

        VAR_7 = -EINVAL;

        goto out;

    }



    







    if (iscsilun->type == TYPE_MEDIUM_CHANGER ||

        iscsilun->type == TYPE_TAPE) {

        VAR_0->sg = 1;

    }



    VAR_7 = 0;



out:

    if (VAR_6 != NULL) {

        g_free(VAR_6);

    }

    if (VAR_4 != NULL) {

        iscsi_destroy_url(VAR_4);

    }



    if (VAR_7) {

        if (VAR_3 != NULL) {

            iscsi_destroy_context(VAR_3);

        }

        memset(iscsilun, 0, sizeof(IscsiLun));

    }

    return VAR_7;

}

static int FUNC_0(BlockDriverState *VAR_0, const char *VAR_1, int VAR_2)
{ IscsiLun *iscsilun = VAR_0->opaque; struct iscsi_context *VAR_3 = NULL; struct VAR_4 *VAR_4 = NULL; struct IscsiTask VAR_5; char *VAR_6 = NULL; int VAR_7; if ((BDRV_SECTOR_SIZE % 512) != 0) { error_report("iSCSI: Invalid BDRV_SECTOR_SIZE. "
"BDRV_SECTOR_SIZE(%lld) is not a multiple "
"of 512", BDRV_SECTOR_SIZE); return -EINVAL; } VAR_4 = iscsi_parse_full_url(VAR_3, VAR_1); if (VAR_4 == NULL) { error_report("Failed to parse URL : %s %s", VAR_1,
iscsi_get_error(VAR_3)); VAR_7 = -EINVAL; goto out; } memset(iscsilun, 0, sizeof(IscsiLun)); VAR_6 = parse_initiator_name(VAR_4->target); VAR_3 = iscsi_create_context(VAR_6); if (VAR_3 == NULL) { error_report("iSCSI: Failed to create iSCSI context."); VAR_7 = -ENOMEM; goto out; } if (iscsi_set_targetname(VAR_3, VAR_4->target)) { error_report("iSCSI: Failed to set target name."); VAR_7 = -EINVAL; goto out; } if (VAR_4->user != NULL) { VAR_7 = iscsi_set_initiator_username_pwd(VAR_3, VAR_4->user,
VAR_4->passwd); if (VAR_7 != 0) { error_report("Failed to set initiator username and password"); VAR_7 = -EINVAL; goto out; } } if (parse_chap(VAR_3, VAR_4->target) != 0) { error_report("iSCSI: Failed to set CHAP user/password"); VAR_7 = -EINVAL; goto out; } if (iscsi_set_session_type(VAR_3, ISCSI_SESSION_NORMAL) != 0) { error_report("iSCSI: Failed to set session type to normal."); VAR_7 = -EINVAL; goto out; } iscsi_set_header_digest(VAR_3, ISCSI_HEADER_DIGEST_NONE_CRC32C); parse_header_digest(VAR_3, VAR_4->target); VAR_5.iscsilun = iscsilun; VAR_5.status = 0; VAR_5.complete = 0; VAR_5.VAR_0 = VAR_0; iscsilun->VAR_3 = VAR_3; iscsilun->lun   = VAR_4->lun; if (iscsi_full_connect_async(VAR_3, VAR_4->portal, VAR_4->lun,
iscsi_connect_cb, &VAR_5)
!= 0) { error_report("iSCSI: Failed to start async connect."); VAR_7 = -EINVAL; goto out; } while (!VAR_5.complete) { iscsi_set_events(iscsilun); qemu_aio_wait(); } if (VAR_5.status != 0) { error_report("iSCSI: Failed to connect to LUN : %s",
iscsi_get_error(VAR_3)); VAR_7 = -EINVAL; goto out; } if (iscsilun->type == TYPE_MEDIUM_CHANGER ||
iscsilun->type == TYPE_TAPE) { VAR_0->sg = 1; } VAR_7 = 0; out:
if (VAR_6 != NULL) { g_free(VAR_6); } if (VAR_4 != NULL) { iscsi_destroy_url(VAR_4); } if (VAR_7) { if (VAR_3 != NULL) { iscsi_destroy_context(VAR_3); } memset(iscsilun, 0, sizeof(IscsiLun)); } return VAR_7; }