VirtualBox

Changeset 26917 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Mar 1, 2010 2:55:10 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
58201
Message:

Storage/iSCSI: implement automatically setting InitiatorName and ISID to globally unique values

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/ISCSIHDDCore.cpp

    r26684 r26917  
    55
    66/*
    7  * Copyright (C) 2006-2009 Sun Microsystems, Inc.
     7 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    330330    /** Size of volume in sectors. */
    331331    uint64_t            cVolume;
    332     /** Total volume size in bytes. Easiert that multiplying the above values all the time. */
     332    /** Total volume size in bytes. Easier that multiplying the above values all the time. */
    333333    uint64_t            cbSize;
    334334
     
    371371    /** Timeout for read operations on the TCP connection (in milliseconds). */
    372372    uint32_t            uReadTimeout;
     373    /** Flag whether to automatically generate the initiator name. */
     374    bool                fAutomaticInitiatorName;
    373375    /** Flag whether to use the host IP stack or DevINIP. */
    374376    bool                fHostIP;
     
    450452*******************************************************************************/
    451453
    452 /** Counter for getting unique instance IDs. */
    453 static uint32_t s_u32iscsiID = 0;
     454/** Default initiator basename. */
     455static const char *s_iscsiDefaultInitiatorBasename = "iqn.2009-08.com.sun.virtualbox.initiator";
    454456
    455457/** Default LUN. */
    456458static const char *s_iscsiConfigDefaultLUN = "0";
    457 
    458 /** Default initiator name. */
    459 static const char *s_iscsiConfigDefaultInitiatorName = "iqn.2009-08.com.sun.virtualbox.initiator";
    460459
    461460/** Default timeout, 10 seconds. */
     
    475474    { "LUN",                s_iscsiConfigDefaultLUN,            VDCFGVALUETYPE_STRING,  VD_CFGKEY_MANDATORY },
    476475    { "TargetAddress",      NULL,                               VDCFGVALUETYPE_STRING,  VD_CFGKEY_MANDATORY },
    477     { "InitiatorName",      s_iscsiConfigDefaultInitiatorName,  VDCFGVALUETYPE_STRING,  0 },
     476    { "InitiatorName",      NULL,                               VDCFGVALUETYPE_STRING,  0 },
    478477    { "InitiatorUsername",  NULL,                               VDCFGVALUETYPE_STRING,  0 },
    479478    { "InitiatorSecret",    NULL,                               VDCFGVALUETYPE_BYTES,   0 },
     
    533532
    534533
     534static int iscsiTransportConnect(PISCSIIMAGE pImage)
     535{
     536    int rc;
     537    if (!pImage->pszHostname)
     538        return VERR_NET_DEST_ADDRESS_REQUIRED;
     539
     540    rc = pImage->pInterfaceNetCallbacks->pfnClientConnect(pImage->pszHostname, pImage->uPort, &pImage->Socket);
     541    if (RT_UNLIKELY(   RT_FAILURE(rc)
     542                    && (   rc == VERR_NET_CONNECTION_REFUSED
     543                        || rc == VERR_NET_CONNECTION_RESET
     544                        || rc == VERR_NET_UNREACHABLE
     545                        || rc == VERR_NET_HOST_UNREACHABLE
     546                        || rc == VERR_NET_CONNECTION_TIMED_OUT)))
     547    {
     548        /* Standardize return value for no connection. */
     549        return VERR_NET_CONNECTION_REFUSED;
     550    }
     551
     552    /* Make initiator name and ISID unique on this host. */
     553    RTNETADDR LocalAddr;
     554    rc = pImage->pInterfaceNetCallbacks->pfnGetLocalAddress(pImage->Socket,
     555                                                            &LocalAddr);
     556    if (RT_FAILURE(rc))
     557        return rc;
     558    if (   LocalAddr.uPort == RTNETADDR_PORT_NA
     559        || LocalAddr.uPort > 65535)
     560        return VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED;
     561    pImage->ISID &= ~65535ULL;
     562    pImage->ISID |= LocalAddr.uPort;
     563    /* Eliminate the port so that it isn't included below. */
     564    LocalAddr.uPort = RTNETADDR_PORT_NA;
     565    if (pImage->fAutomaticInitiatorName)
     566    {
     567        if (pImage->pszInitiatorName)
     568            RTStrFree(pImage->pszInitiatorName);
     569        RTStrAPrintf(&pImage->pszInitiatorName, "%s:01:%RTnaddr",
     570                     s_iscsiDefaultInitiatorBasename, &LocalAddr);
     571        if (!pImage->pszInitiatorName)
     572            return VERR_NO_MEMORY;
     573    }
     574    return VINF_SUCCESS;
     575}
     576
     577
    535578static int iscsiTransportRead(PISCSIIMAGE pImage, PISCSIRES paResponse, unsigned int cnResponse)
    536579{
     
    543586    if (pImage->Socket == NIL_RTSOCKET)
    544587    {
    545         /* Attempt to reconnect if the connection was previously broken. */
    546         if (pImage->pszHostname != NULL)
    547         {
    548             rc = pImage->pInterfaceNetCallbacks->pfnClientConnect(pImage->pszHostname, pImage->uPort, &pImage->Socket);
    549             if (RT_UNLIKELY(   RT_FAILURE(rc)
    550                             && (   rc == VERR_NET_CONNECTION_REFUSED
    551                                 || rc == VERR_NET_CONNECTION_RESET
    552                                 || rc == VERR_NET_UNREACHABLE
    553                                 || rc == VERR_NET_HOST_UNREACHABLE
    554                                 || rc == VERR_NET_CONNECTION_TIMED_OUT)))
    555             {
    556                 /* Standardize return value for no connection. */
    557                 rc = VERR_NET_CONNECTION_REFUSED;
    558             }
    559         }
     588        /* Reconnecting makes no sense in this case, as there will be nothing
     589         * to receive. We would just run into a timeout. */
     590        rc = VERR_BROKEN_PIPE;
    560591    }
    561592
     
    679710    {
    680711        /* Attempt to reconnect if the connection was previously broken. */
    681         if (pImage->pszHostname != NULL)
    682         {
    683             rc = pImage->pInterfaceNetCallbacks->pfnClientConnect(pImage->pszHostname, pImage->uPort, &pImage->Socket);
    684             if (RT_UNLIKELY(   RT_FAILURE(rc)
    685                             && (   rc == VERR_NET_CONNECTION_REFUSED
    686                                 || rc == VERR_NET_CONNECTION_RESET
    687                                 || rc == VERR_NET_UNREACHABLE
    688                                 || rc == VERR_NET_HOST_UNREACHABLE
    689                                 || rc == VERR_NET_CONNECTION_TIMED_OUT)))
    690             {
    691                 /* Standardize return value for no connection. */
    692                 rc = VERR_NET_CONNECTION_REFUSED;
    693             }
    694         }
     712        rc = iscsiTransportConnect(pImage);
    695713    }
    696714
     
    822840    }
    823841
    824     if (RT_FAILURE(rc))
     842    if (RT_SUCCESS(rc))
     843    {
     844        if (pImage->Socket == NIL_RTSOCKET)
     845            rc = iscsiTransportConnect(pImage);
     846    }
     847    else
    825848    {
    826849        if (pImage->pszHostname)
     
    832855    }
    833856
    834     /* Note that in this implementation the actual connection establishment is
    835      * delayed until a PDU is read or written. */
    836857    LogFlowFunc(("returns %Rrc\n", rc));
    837858    return rc;
     
    917938
    918939restart:
     940    if (pImage->Socket == NIL_RTSOCKET)
     941        rc = iscsiTransportOpen(pImage);
     942
    919943    pImage->state = ISCSISTATE_IN_LOGIN;
    920944    pImage->ITT = 1;
     
    22302254    if (pImage->pszInitiatorName)
    22312255    {
    2232         RTMemFree(pImage->pszInitiatorName);
     2256        if (pImage->fAutomaticInitiatorName)
     2257            RTStrFree(pImage->pszInitiatorName);
     2258        else
     2259            RTMemFree(pImage->pszInitiatorName);
    22332260        pImage->pszInitiatorName = NULL;
    22342261    }
     
    23092336    }
    23102337
    2311     pImage->ISID            = 0x800000000000ULL | 0x001234560000ULL | (0x00000000cba0ULL + ASMAtomicIncU32(&s_u32iscsiID));
     2338    /* This ISID will be adjusted later to make it unique on this host. */
     2339    pImage->ISID            = 0x800000000000ULL | 0x001234560000ULL;
    23122340    pImage->cISCSIRetries   = 10;
    23132341    pImage->state           = ISCSISTATE_FREE;
     
    23422370        goto out;
    23432371    }
    2344     rc = VDCFGQueryStringAllocDef(pImage->pInterfaceConfigCallbacks,
    2345                                   pImage->pInterfaceConfig->pvUser,
    2346                                   "InitiatorName", &pImage->pszInitiatorName,
    2347                                   s_iscsiConfigDefaultInitiatorName);
     2372    rc = VDCFGQueryStringAlloc(pImage->pInterfaceConfigCallbacks,
     2373                               pImage->pInterfaceConfig->pvUser,
     2374                               "InitiatorName", &pImage->pszInitiatorName);
     2375    if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
     2376    {
     2377        pImage->fAutomaticInitiatorName = true;
     2378        rc = VINF_SUCCESS;
     2379    }
    23482380    if (RT_FAILURE(rc))
    23492381    {
     
    24912523
    24922524    /*
    2493      * Establish the iSCSI transport connection.
     2525     * Attach to the iSCSI target. This implicitly establishes the iSCSI
     2526     * transport connection.
    24942527     */
    2495     rc = iscsiTransportOpen(pImage);
    2496     if (RT_SUCCESS(rc))
    2497         rc = iscsiAttach(pImage);
     2528    rc = iscsiAttach(pImage);
    24982529
    24992530    if (RT_FAILURE(rc))
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette