VirtualBox

Changeset 86134 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Sep 16, 2020 3:39:09 PM (4 years ago)
Author:
vboxsync
Message:

Main: bugref:9224: Added NVME drives enumeration on Linux. Fixed the showing the model of the drive if additional info is not available

Location:
trunk/src/VBox
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageList.cpp

    r85929 r86134  
    16021602    {
    16031603        ComPtr<IHostDrive> pHostDrive = apHostDrives[i];
    1604 
     1604        /*
     1605         * The drive path and the model are obtained using different way
     1606         * outside of the IHostDrive object, therefore, they are defined
     1607         * even if another info is not available.
     1608         */
    16051609        com::Bstr bstrDrivePath;
    16061610        CHECK_ERROR(pHostDrive,COMGETTER(DrivePath)(bstrDrivePath.asOutParam()));
     
    16081612
    16091613        com::Bstr bstrModel;
     1614        CHECK_ERROR(pHostDrive,COMGETTER(Model)(bstrModel.asOutParam()));
     1615        if (bstrModel.isNotEmpty())
     1616            RTPrintf("Model:       %ls\n", bstrModel.raw());
     1617        else
     1618            RTPrintf("Model:       Unknown\n");
     1619
    16101620        com::Bstr bstrUuidDisk;
    16111621        ULONG cbSectorSize = 0;
     
    16131623        PartitioningType_T partitioningType;
    16141624        HRESULT hrc;
    1615         if (   SUCCEEDED(hrc = pHostDrive->COMGETTER(Model)(bstrModel.asOutParam()))
    1616             && SUCCEEDED(hrc = pHostDrive->COMGETTER(Uuid)(bstrUuidDisk.asOutParam()))
     1625        if (   SUCCEEDED(hrc = pHostDrive->COMGETTER(Uuid)(bstrUuidDisk.asOutParam()))
    16171626            && SUCCEEDED(hrc = pHostDrive->COMGETTER(SectorSize)(&cbSectorSize))
    16181627            && SUCCEEDED(hrc = pHostDrive->COMGETTER(Size)(&cbSize))
    16191628            && SUCCEEDED(hrc = pHostDrive->COMGETTER(PartitioningType)(&partitioningType)))
    16201629        {
    1621             if (bstrModel.isNotEmpty())
    1622                 RTPrintf("Model:       %ls\n", bstrModel.raw());
    1623             else
    1624                 RTPrintf("Model:       Unknown\n");
    1625 
    16261630            if (partitioningType == PartitioningType_GPT || com::Guid(bstrUuidDisk).isZero())
    16271631                RTPrintf("UUID:        %ls\n", bstrUuidDisk.raw());
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r86069 r86134  
    1065010650    </attribute>
    1065110651
    10652     <attribute name="model" type="wstring" readonly="yes">
     10652    <attribute name="model" type="wstring" readonly="yes" wrap-hint-server="limitedcaller">
    1065310653     <desc>
    1065410654       The model string of the drive if available.
  • trunk/src/VBox/Main/src-server/linux/HostHardwareLinux.cpp

    r85932 r86134  
    3838#include <linux/fd.h>
    3939#include <linux/major.h>
     40
     41#include <linux/version.h>
     42#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)
     43# include <linux/nvme_ioctl.h>
     44#else
     45# include <linux/nvme.h>
     46#endif
    4047#include <scsi/scsi.h>
    4148
     
    349356    AssertReturnVoid(!pszUdi || cbUdi > 0);
    350357
    351     size_t cchVendor = strLenStripped(pcszVendor);
    352358    size_t cchModel = strLenStripped(pcszModel);
     359    /*
     360     * Vendor and Model strings can contain trailing spaces.
     361     * Create trimmed copy of them because we should not modify
     362     * original strings.
     363     */
     364    char* pszStartTrimmed = RTStrStripL(pcszVendor);
     365    char* pszVendor = RTStrDup(pszStartTrimmed);
     366    RTStrStripR(pszVendor);
     367    pszStartTrimmed = RTStrStripL(pcszModel);
     368    char* pszModel = RTStrDup(pszStartTrimmed);
     369    RTStrStripR(pszModel);
     370
     371    size_t cbVendor = strlen(pszVendor);
    353372
    354373    /* Create a cleaned version of the model string for the UDI string. */
     
    365384    if (pszDesc)
    366385    {
    367         if (cchVendor > 0)
    368         {
    369             RTStrPrintf(pszDesc, cbDesc, "%.*s %s", cchVendor, pcszVendor, cchModel > 0 ? pcszModel : "(unknown drive model)");
     386        if (cbVendor > 0)
     387        {
     388            RTStrPrintf(pszDesc, cbDesc, "%.*s %s", cbVendor, pszVendor, strlen(pszModel) > 0 ? pszModel : "(unknown drive model)");
    370389            RTStrPurgeEncoding(pszDesc);
    371390        }
    372391        else
    373             RTStrCopy(pszDesc, cbDesc, pcszModel);
     392            RTStrCopy(pszDesc, cbDesc, pszModel);
    374393    }
    375394    /* Construct the UDI string */
     
    383402}
    384403
     404/**
     405 * Check whether the device is the NVME device.
     406 * @returns true on success, false if the name was not available (i.e. the
     407 *          device was not readable, or the file name wasn't a NVME device)
     408 * @param  pcszNode     the path to the device node for the device
     409 */
     410static bool probeNVME(const char *pcszNode) RT_NOTHROW_DEF
     411{
     412    AssertPtrReturn(pcszNode, false);
     413    RTFILE File;
     414    int rc = RTFileOpen(&File, pcszNode, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_NON_BLOCK);
     415    if (RT_SUCCESS(rc))
     416    {
     417        int rcIoCtl;
     418        rc = RTFileIoCtl(File, NVME_IOCTL_ID, NULL, 0, &rcIoCtl);
     419        RTFileClose(File);
     420        if (RT_SUCCESS(rc) && rcIoCtl >= 0)
     421            return true;
     422    }
     423    return false;
     424}
    385425
    386426/**
     
    736776        int64_t type = 0;
    737777        int rc = RTLinuxSysFsReadIntFile(10, &type, "block/%s/device/type", mpcszName);
    738         if (RT_SUCCESS(rc) && type != TYPE_DISK)
    739             return;
     778        if (!RT_SUCCESS(rc) || type != TYPE_DISK)
     779        {
     780            if (noProbe() || !probeNVME(mszNode))
     781            {
     782                char szDriver[16];
     783                rc = RTLinuxSysFsGetLinkDest(szDriver, sizeof(szDriver), NULL, "block/%s/%s",
     784                                                 mpcszName, "device/device/driver");
     785                if (RT_FAILURE(rc) || RTStrCmp(szDriver, "nvme"))
     786                        return;
     787            }
     788        }
    740789        char szVendor[128];
    741         rc = RTLinuxSysFsReadStrFile(szVendor, sizeof(szVendor), NULL, "block/%s/device/vendor", mpcszName);
     790        char szModel[128];
     791        size_t cbRead = 0;
     792        rc = RTLinuxSysFsReadStrFile(szVendor, sizeof(szVendor), &cbRead, "block/%s/device/vendor", mpcszName);
     793        szVendor[cbRead] = '\0';
     794        /* Assume the model is always present. Vendor is not present for NVME disks */
     795        cbRead = 0;
     796        rc = RTLinuxSysFsReadStrFile(szModel, sizeof(szModel), &cbRead, "block/%s/device/model", mpcszName);
     797        szModel[cbRead] = '\0';
    742798        if (RT_SUCCESS(rc))
    743799        {
    744             char szModel[128];
    745             rc = RTLinuxSysFsReadStrFile(szModel, sizeof(szModel), NULL, "block/%s/device/model", mpcszName);
    746             if (RT_SUCCESS(rc))
    747             {
    748                 misValid = true;
    749                 dvdCreateDeviceStrings(szVendor, szModel, mszDesc, sizeof(mszDesc), mszUdi, sizeof(mszUdi));
    750                 return;
    751             }
     800            misValid = true;
     801            dvdCreateDeviceStrings(szVendor, szModel, mszDesc, sizeof(mszDesc), mszUdi, sizeof(mszUdi));
    752802        }
    753803    }
Note: See TracChangeset for help on using the changeset viewer.

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