VirtualBox

Changeset 74990 in vbox


Ignore:
Timestamp:
Oct 23, 2018 9:26:39 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
126014
Message:

iSCSI: If LUN not explicitly specified and REPORT LUNS shows a single LUN available, use that. Helps with iSCSI targets that default to a single non-zero LUN, such as Synology DSM 6.2. See bugref:9163

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Storage/ISCSI.cpp

    r74107 r74990  
    570570    /** Flag whether to automatically generate the initiator name. */
    571571    bool                fAutomaticInitiatorName;
     572    /** Flag whether to automatically determine the LUN. */
     573    bool                fAutomaticLUN;
    572574    /** Flag whether to use the host IP stack or DevINIP. */
    573575    bool                fHostIP;
     
    40614063        return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("iSCSI: configuration error: failed to read InitiatorName as string"));
    40624064
    4063     rc = VDCFGQueryStringAllocDef(pImage->pIfConfig, "LUN", &pszLUN, s_iscsiConfigDefaultLUN);
    4064     if (RT_FAILURE(rc))
     4065    rc = VDCFGQueryStringAlloc(pImage->pIfConfig, "LUN", &pszLUN);
     4066    if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
     4067    {
     4068        rc = VINF_SUCCESS;
     4069        pImage->fAutomaticLUN = true;
     4070    }
     4071    else if (RT_FAILURE(rc))
    40654072        return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("iSCSI: configuration error: failed to read LUN as string"));
    40664073
    4067     pszLUNInitial = pszLUN;
    4068     if (!strncmp(pszLUN, "enc", 3))
    4069     {
    4070         fLunEncoded = true;
    4071         pszLUN += 3;
    4072     }
    4073     rc = RTStrToUInt64Full(pszLUN, 0, &pImage->LUN);
    4074     if (RT_FAILURE(rc))
    4075         rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("iSCSI: configuration error: failed to convert LUN to integer"));
    4076 
    4077     RTMemFree(pszLUNInitial);
     4074    if (pImage->fAutomaticLUN)
     4075        pImage->LUN = 0;    /* Default to LUN 0. */
     4076    else
     4077    {
     4078        pszLUNInitial = pszLUN;
     4079        if (!strncmp(pszLUN, "enc", 3))
     4080        {
     4081            fLunEncoded = true;
     4082            pszLUN += 3;
     4083        }
     4084        rc = RTStrToUInt64Full(pszLUN, 0, &pImage->LUN);
     4085        if (RT_FAILURE(rc))
     4086            rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("iSCSI: configuration error: failed to convert LUN to integer"));
     4087
     4088        RTMemFree(pszLUNInitial);
     4089    }
    40784090    if (RT_SUCCESS(rc) && !fLunEncoded)
    40794091    {
     
    41974209
    41984210    /*
    4199      * Inquire available LUNs - purely dummy request.
     4211     * Inquire available LUNs.
    42004212     */
    42014213    RT_ZERO(sr.abCDB);
     
    42284240    if (RT_FAILURE(rc))
    42294241        LogRel(("iSCSI: Could not get LUN info for target %s, rc=%Rrc\n", pImage->pszTargetName, rc));
     4242
     4243    /* If there is a single LUN on the target, then either verify that it matches the explicitly
     4244     * configured LUN, or just use it if a LUN was not configured (defaulted to 0). For multi-LUN targets,
     4245     * require a correctly configured LUN.
     4246     */
     4247    uint32_t    cbLuns = (rlundata[0] << 24) | (rlundata[1] << 16) | (rlundata[2] << 8) | rlundata[3];
     4248    unsigned    cLuns  = cbLuns / 8;
     4249
     4250    /* Dig out the first LUN. */
     4251    uint64_t    uTgtLun = 0;
     4252    if ((rlundata[8] & 0xc0) == 0)
     4253    {
     4254        /* Single-byte LUN in 0-255 range. */
     4255        uTgtLun = rlundata[9];
     4256    }
     4257    else if ((rlundata[8] & 0xc0) == 0x40)
     4258    {
     4259        /* Two-byte LUN in 256-16383 range. */
     4260        uTgtLun = rlundata[9] | ((rlundata[8] & 0x3f) << 8);
     4261        uTgtLun = (uTgtLun << 48) | RT_BIT_64(62);
     4262    }
     4263    else
     4264        rc = vdIfError(pImage->pIfError, VERR_OUT_OF_RANGE, RT_SRC_POS, N_("iSCSI: Reported LUN number out of range (0-16383)"));
     4265    if (RT_FAILURE(rc))
     4266        return rc;
     4267
     4268    LogRel(("iSCSI: %u LUN(s), first LUN %RX64\n", cLuns, uTgtLun));
     4269
     4270    /* Convert the LUN back into the 64-bit format. */
     4271    if (uTgtLun <= 255)
     4272        uTgtLun = uTgtLun << 48;
     4273    else
     4274    {
     4275        Assert(uTgtLun <= 16383);
     4276        uTgtLun = (uTgtLun << 48) | RT_BIT_64(62);
     4277    }
     4278
     4279    if (cLuns == 1)
     4280    {
     4281        /* NB: It is valid to have a single LUN other than zero, at least in SPC-3. */
     4282        if (pImage->fAutomaticLUN)
     4283            pImage->LUN = uTgtLun;
     4284        else if (pImage->LUN != uTgtLun)
     4285            rc = vdIfError(pImage->pIfError, VERR_VD_ISCSI_INVALID_TYPE, RT_SRC_POS, N_("iSCSI: configuration error: Configured LUN does not match what target provides"));
     4286    }
    42304287
    42314288    return 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