VirtualBox

Changeset 34587 in vbox


Ignore:
Timestamp:
Dec 1, 2010 8:30:02 PM (14 years ago)
Author:
vboxsync
Message:

Main: Bandwidth groups for disks (and later network)

This introduces two new interfaces. The first one named IBandwidthGroup
represents one I/O limit and can be assigned to several mediums which
share this limit (which works only for harddisk images with the disabled
host cache).
The second one IBandwdithControl manages the groups and can create new ones
and destroy them if not required anymore.

VBoxManage: commands to access the bandwidth groups

Syntax:
VBoxManage storageattach <uuid|vmname>

...
--bandwidthgroup <name>

--bandwidthgroup assigns the specified device to the given group.

VBoxManage bandwidthctl <uuid|vmname>

--name <name>
--add disk|network
--limit <megabytes per second>
--delete

The --name parameter gives the name of the bandwidth group.
--add creates a new group of the given type (only disk is implemented so far)

with the given name.

--limit sets the limit to the given amount of MB/s

Note that limit can be changed while the VM is running. The VM
will immediately pick up the new limit for the given group name.

--delete deletes the group with the given name if it isn't used anymore.

Trying to delete a still used group will result in an error.

Example:

VBoxManage bandwidthctl "Test VM" --name Limit --add disk --limit 20
Creates a group named Test having a 20 MB/s limit.

VBoxManage storageattach "Test VM" --storagectl "SATA Controller" --port 0 --device 0 --type hdd --medium test.vdi --bandwidthgroup Limit
Adds a new disk to the SATA controller and assigns the bandwidth group Limit to it.

VBoxManage storageattach "Test VM" --storagectl "SATA Controller" --port 0 --device 0 --type hdd --medium test.vdi --bandwidthgroup none
Removes the bandwidth limit from the disk.

VBoxManage bandwidthctl "Test VM" --name Limit --add disk --limit 10
Changes the limit of bandwidth group Limit to 10 MB/s. If the VM is running the limit will be picked up
immediately.

Location:
trunk
Files:
5 added
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/settings.h

    r34574 r34587  
    653653 * your settings might never get saved.
    654654 */
     655struct BandwidthGroup
     656{
     657    BandwidthGroup()
     658        : cMaxMbPerSec(0),
     659          enmType(BandwidthGroupType_Null)
     660    {}
     661
     662    bool operator==(const BandwidthGroup &i) const
     663    {
     664        return (   (strName      == i.strName)
     665                && (cMaxMbPerSec == i.cMaxMbPerSec)
     666                && (enmType      == i.enmType));
     667    }
     668
     669    com::Utf8Str         strName;
     670    uint32_t             cMaxMbPerSec;
     671    BandwidthGroupType_T enmType;
     672};
     673typedef std::list<BandwidthGroup> BandwidthGroupList;
     674
     675/**
     676 * NOTE: If you add any fields in here, you must update a) the constructor and b)
     677 * the operator== which is used by MachineConfigFile::operator==(), or otherwise
     678 * your settings might never get saved.
     679 */
    655680struct IoSettings
    656681{
     
    659684    bool operator==(const IoSettings &i) const
    660685    {
    661         return (   (fIoCacheEnabled  == i.fIoCacheEnabled)
    662                 && (ulIoCacheSize    == i.ulIoCacheSize));
     686        return (   (fIoCacheEnabled   == i.fIoCacheEnabled)
     687                && (ulIoCacheSize     == i.ulIoCacheSize)
     688                && (llBandwidthGroups == i.llBandwidthGroups));
    663689    }
    664690
    665     bool            fIoCacheEnabled;
    666     uint32_t        ulIoCacheSize;
     691    bool               fIoCacheEnabled;
     692    uint32_t           ulIoCacheSize;
     693    BandwidthGroupList llBandwidthGroups;
    667694};
    668695
     
    754781          fPassThrough(false),
    755782          lPort(0),
    756           lDevice(0),
    757           ulBandwidthLimit(0)
     783          lDevice(0)
    758784    {}
    759785
     
    767793    int32_t             lPort;
    768794    int32_t             lDevice;
    769 
    770     uint32_t            ulBandwidthLimit;
    771795
    772796    // if an image file is attached to the device (ISO, RAW, or hard disk image such as VDI),
     
    777801    // for DVDs and floppies, the attachment can also be a host device:
    778802    com::Utf8Str        strHostDriveSrc;        // if != NULL, value of <HostDrive>/@src
     803
     804    // Bandwidth group the device is attached to.
     805    com::Utf8Str        strBwGroup;
    779806};
    780807typedef std::list<AttachedDevice> AttachedDevicesList;
  • trunk/src/VBox/Frontends/VBoxManage/Makefile.kmk

    r33590 r34587  
    5050        VBoxManageSnapshot.cpp \
    5151        VBoxManageStorageController.cpp \
    52         VBoxManageUSB.cpp
     52        VBoxManageUSB.cpp \
     53        VBoxManageBandwidthControl.cpp
    5354endif # !VBOX_ONLY_DOCS
    5455
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp

    r34244 r34587  
    432432            { "dhcpserver",       USAGE_DHCPSERVER,        handleDHCPServer},
    433433            { "extpack",          USAGE_EXTPACK,           handleExtPack},
     434            { "bandwidthctl",     USAGE_BANDWIDTHCONTROL,  handleBandwidthControl},
    434435            { NULL,               0,                       NULL }
    435436        };
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h

    r34244 r34587  
    9898#define USAGE_PASSWORDHASH          RT_BIT_64(54)
    9999#define USAGE_EXTPACK               RT_BIT_64(55)
     100#define USAGE_BANDWIDTHCONTROL      RT_BIT_64(56)
    100101#define USAGE_ALL                   (~(uint64_t)0)
    101102/** @} */
     
    241242int handleDHCPServer(HandlerArg *a);
    242243
     244/* VBoxManageBandwidthControl.cpp */
     245int handleBandwidthControl(HandlerArg *a);
     246
    243247#endif /* !VBOX_ONLY_DOCS */
    244248
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp

    r34574 r34587  
    464464                     "                                      <uuid>|<filename>|host:<drive>]\n"
    465465                     "                            [--passthrough on|off]\n"
     466                     "                            [--bandwidthgroup <name>]\n"
    466467                     "                            [--forceunmount]\n"
    467468                     "\n");
     
    481482                     "                            [--bootable on|off]\n"
    482483                     "                            [--remove]\n"
     484                     "\n");
     485    }
     486
     487    if (u64Cmd & USAGE_BANDWIDTHCONTROL)
     488    {
     489        RTStrmPrintf(pStrm,
     490                     "VBoxManage bandwidthctl     <uuid|vmname>\n"
     491                     "                            --name <name>\n"
     492                     "                            [--add disk|network]\n"
     493                     "                            [--limit <megabytes per second>\n"
     494                     "                            [--delete]\n"
    483495                     "\n");
    484496    }
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp

    r34010 r34587  
    5151    { "--type",           't', RTGETOPT_REQ_STRING },
    5252    { "--passthrough",    'h', RTGETOPT_REQ_STRING },
     53    { "--bandwidthgroup", 'b', RTGETOPT_REQ_STRING },
    5354    { "--forceunmount",   'f', RTGETOPT_REQ_NOTHING },
    5455};
     
    6566    const char *pszMedium = NULL;
    6667    const char *pszPassThrough = NULL;
     68    const char *pszBandwidthGroup = NULL;
    6769    RTGETOPTUNION ValueUnion;
    6870    RTGETOPTSTATE GetState;
     
    127129                if (ValueUnion.psz)
    128130                    pszPassThrough = ValueUnion.psz;
     131                else
     132                    rc = E_FAIL;
     133                break;
     134            }
     135
     136            case 'b':   // bandwidthgroup <name>
     137            {
     138                if (ValueUnion.psz)
     139                    pszBandwidthGroup = ValueUnion.psz;
    129140                else
    130141                    rc = E_FAIL;
     
    185196    {
    186197        errorArgument("Drive passthrough state can't be changed while the VM is running\n");
     198        goto leave;
     199    }
     200
     201    if (fRunTime && pszBandwidthGroup)
     202    {
     203        errorArgument("Bandwidth group can't be changed while the VM is running\n");
    187204        goto leave;
    188205    }
     
    626643    }
    627644
     645    if (   pszBandwidthGroup
     646        && !fRunTime
     647        && SUCCEEDED(rc))
     648    {
     649
     650        if (!RTStrICmp(pszBandwidthGroup, "none"))
     651        {
     652            /* Just remove the bandwidth gorup. */
     653            CHECK_ERROR(machine, SetBandwidthGroupForDevice(Bstr(pszCtl).raw(),
     654                                                            port, device, NULL));
     655        }
     656        else
     657        {
     658            ComPtr<IBandwidthControl> bwCtrl;
     659            ComPtr<IBandwidthGroup> bwGroup;
     660
     661            CHECK_ERROR(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()));
     662
     663            if (SUCCEEDED(rc))
     664            {
     665                CHECK_ERROR(bwCtrl, GetBandwidthGroup(Bstr(pszBandwidthGroup).raw(), bwGroup.asOutParam()));
     666                if (SUCCEEDED(rc))
     667                {
     668                    CHECK_ERROR(machine, SetBandwidthGroupForDevice(Bstr(pszCtl).raw(),
     669                                                                    port, device, bwGroup));
     670                }
     671            }
     672        }
     673    }
     674
    628675    /* commit changes */
    629676    if (SUCCEEDED(rc))
  • trunk/src/VBox/Main/ConsoleImpl.cpp

    r34558 r34587  
    9797#include <VBox/ssm.h>
    9898#include <VBox/version.h>
     99#include <VBox/pdmasynccompletion.h>
    99100#ifdef VBOX_WITH_USB
    100101# include <VBox/pdmusb.h>
     
    43214322    return E_FAIL;
    43224323#endif  /* !VBOX_WITH_USB */
     4324}
     4325
     4326/**
     4327 * Called by IInternalSessionControl::OnBandwidthGroupChange().
     4328 *
     4329 * @note Locks this object for writing.
     4330 */
     4331HRESULT Console::onBandwidthGroupChange(IBandwidthGroup *aBandwidthGroup)
     4332{
     4333    LogFlowThisFunc(("\n"));
     4334
     4335    AutoCaller autoCaller(this);
     4336    AssertComRCReturnRC(autoCaller.rc());
     4337
     4338    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     4339
     4340    HRESULT rc = S_OK;
     4341
     4342    /* don't trigger the CPU priority change if the VM isn't running */
     4343    if (mpVM)
     4344    {
     4345        /* protect mpVM */
     4346        AutoVMCaller autoVMCaller(this);
     4347        if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
     4348
     4349        if (   mMachineState == MachineState_Running
     4350            || mMachineState == MachineState_Teleporting
     4351            || mMachineState == MachineState_LiveSnapshotting
     4352            )
     4353        {
     4354            /* No need to call in the EMT thread. */
     4355            ULONG cMax;
     4356            Bstr strName;
     4357            rc = aBandwidthGroup->COMGETTER(Name)(strName.asOutParam());
     4358            if (SUCCEEDED(rc))
     4359                rc = aBandwidthGroup->COMGETTER(MaxMbPerSec)(&cMax);
     4360
     4361            if (SUCCEEDED(rc))
     4362            {
     4363                int vrc;
     4364                vrc = PDMR3AsyncCompletionBwMgrSetMaxForFile(mpVM, Utf8Str(strName).c_str(),
     4365                                                             cMax * _1M);
     4366                AssertRC(vrc);
     4367            }
     4368        }
     4369        else
     4370            rc = setInvalidMachineStateError();
     4371    }
     4372
     4373    /* notify console callbacks on success */
     4374    if (SUCCEEDED(rc))
     4375        fireBandwidthGroupChangedEvent(mEventSource, aBandwidthGroup);
     4376
     4377    LogFlowThisFunc(("Leaving rc=%#x\n", rc));
     4378    return rc;
    43234379}
    43244380
  • trunk/src/VBox/Main/ConsoleImpl2.cpp

    r34515 r34587  
    805805        hrc = pMachine->COMGETTER(IoCacheSize)(&ioCacheSize);                               H();
    806806        InsertConfigInteger(pPDMBlkCache, "CacheSize", ioCacheSize * _1M);
     807
     808        /*
     809         * Bandwidth groups.
     810         */
     811        PCFGMNODE pAc;
     812        PCFGMNODE pAcFile;
     813        PCFGMNODE pAcFileBwGroups;
     814        ComPtr<IBandwidthControl> bwCtrl;
     815        com::SafeIfaceArray<IBandwidthGroup> bwGroups;
     816
     817        hrc = pMachine->COMGETTER(BandwidthControl)(bwCtrl.asOutParam());                   H();
     818
     819        hrc = bwCtrl->GetAllBandwidthGroups(ComSafeArrayAsOutParam(bwGroups));              H();
     820
     821        InsertConfigNode(pPDM, "AsyncCompletion", &pAc);
     822        InsertConfigNode(pAc,  "File", &pAcFile);
     823        InsertConfigNode(pAcFile,  "BwGroups", &pAcFileBwGroups);
     824
     825        for (size_t i = 0; i < bwGroups.size(); i++)
     826        {
     827            Bstr strName;
     828            ULONG cMaxMbPerSec;
     829            BandwidthGroupType_T enmType;
     830
     831            hrc = bwGroups[i]->COMGETTER(Name)(strName.asOutParam());                       H();
     832            hrc = bwGroups[i]->COMGETTER(Type)(&enmType);                                   H();
     833            hrc = bwGroups[i]->COMGETTER(MaxMbPerSec)(&cMaxMbPerSec);                       H();
     834
     835            if (enmType == BandwidthGroupType_Disk)
     836            {
     837                PCFGMNODE pBwGroup;
     838                InsertConfigNode(pAcFileBwGroups, Utf8Str(strName).c_str(), &pBwGroup);
     839                InsertConfigInteger(pBwGroup, "Max", cMaxMbPerSec * _1M);
     840                InsertConfigInteger(pBwGroup, "Start", cMaxMbPerSec * _1M);
     841                InsertConfigInteger(pBwGroup, "Step", 0);
     842            }
     843        }
    807844
    808845        /*
     
    28512888        BOOL fPassthrough;
    28522889        hrc = pMediumAtt->COMGETTER(Passthrough)(&fPassthrough);                            H();
     2890
     2891        ComObjPtr<IBandwidthGroup> pBwGroup;
     2892        Bstr strBwGroup;
     2893        hrc = pMediumAtt->COMGETTER(BandwidthGroup)(pBwGroup.asOutParam());                 H();
     2894
     2895        if (!pBwGroup.isNull())
     2896        {
     2897            hrc = pBwGroup->COMGETTER(Name)(strBwGroup.asOutParam());                       H();
     2898        }
     2899
    28532900        rc = configMedium(pLunL0,
    28542901                        !!fPassthrough,
     
    28592906                        uMergeSource,
    28602907                        uMergeTarget,
     2908                        strBwGroup.isEmpty() ? NULL : Utf8Str(strBwGroup).c_str(),
    28612909                        pMedium,
    28622910                        aMachineState,
     
    28992947                          unsigned uMergeSource,
    29002948                          unsigned uMergeTarget,
     2949                          const char *pcszBwGroup,
    29012950                          IMedium *pMedium,
    29022951                          MachineState_T aMachineState,
     
    30933142                        InsertConfigString(pCfg, "Type", "HardDisk");
    30943143                }
     3144
     3145                if (pcszBwGroup)
     3146                    InsertConfigString(pCfg, "BwGroup", pcszBwGroup);
    30953147
    30963148                /* Pass all custom parameters. */
  • trunk/src/VBox/Main/MachineImpl.cpp

    r34360 r34587  
    4949#include "DisplayImpl.h"
    5050#include "DisplayUtils.h"
     51#include "BandwidthControlImpl.h"
    5152
    5253#ifdef VBOX_WITH_USB
     
    36573658                          aType,
    36583659                          fIndirect,
    3659                           0 /* No bandwidth limit */);
     3660                          NULL);
    36603661    if (FAILED(rc)) return rc;
    36613662
     
    37843785    return S_OK;
    37853786}
     3787
     3788STDMETHODIMP Machine::SetBandwidthGroupForDevice(IN_BSTR aControllerName, LONG aControllerPort,
     3789                                                 LONG aDevice, IBandwidthGroup *aBandwidthGroup)
     3790{
     3791    CheckComArgStrNotEmptyOrNull(aControllerName);
     3792
     3793    LogFlowThisFunc(("aControllerName=\"%ls\" aControllerPort=%ld aDevice=%ld\n",
     3794                     aControllerName, aControllerPort, aDevice));
     3795
     3796    AutoCaller autoCaller(this);
     3797    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     3798
     3799    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     3800
     3801    HRESULT rc = checkStateDependency(MutableStateDep);
     3802    if (FAILED(rc)) return rc;
     3803
     3804    AssertReturn(mData->mMachineState != MachineState_Saved, E_FAIL);
     3805
     3806    if (Global::IsOnlineOrTransient(mData->mMachineState))
     3807        return setError(VBOX_E_INVALID_VM_STATE,
     3808                        tr("Invalid machine state: %s"),
     3809                        Global::stringifyMachineState(mData->mMachineState));
     3810
     3811    MediumAttachment *pAttach = findAttachment(mMediaData->mAttachments,
     3812                                               aControllerName,
     3813                                               aControllerPort,
     3814                                               aDevice);
     3815    if (!pAttach)
     3816        return setError(VBOX_E_OBJECT_NOT_FOUND,
     3817                        tr("No storage device attached to device slot %d on port %d of controller '%ls'"),
     3818                        aDevice, aControllerPort, aControllerName);
     3819
     3820
     3821    setModified(IsModified_Storage);
     3822    mMediaData.backup();
     3823
     3824    ComObjPtr<BandwidthGroup> group = static_cast<BandwidthGroup*>(aBandwidthGroup);
     3825    if (aBandwidthGroup && group.isNull())
     3826        return setError(E_INVALIDARG, "The given bandwidth group pointer is invalid");
     3827
     3828    AutoWriteLock attLock(pAttach COMMA_LOCKVAL_SRC_POS);
     3829
     3830    pAttach->updateBandwidthGroup(group);
     3831
     3832    return S_OK;
     3833}
     3834
    37863835
    37873836STDMETHODIMP Machine::MountMedium(IN_BSTR aControllerName,
     
    57685817    SafeIfaceArray<IPciDeviceAttachment> assignments(mPciDeviceAssignments);
    57695818    assignments.detachTo(ComSafeArrayOutArg(aAssignments));
     5819
     5820    return S_OK;
     5821}
     5822
     5823STDMETHODIMP Machine::COMGETTER(BandwidthControl)(IBandwidthControl **aBandwidthControl)
     5824{
     5825    CheckComArgOutPointerValid(aBandwidthControl);
     5826
     5827    AutoCaller autoCaller(this);
     5828    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     5829
     5830    mBandwidthControl.queryInterfaceTo(aBandwidthControl);
    57705831
    57715832    return S_OK;
     
    66286689    }
    66296690
     6691    /* create the bandwidth control */
     6692    unconst(mBandwidthControl).createObject();
     6693    mBandwidthControl->init(this);
     6694
    66306695    return S_OK;
    66316696}
     
    66486713
    66496714    /* tell all our other child objects we've been uninitialized */
     6715    if (mBandwidthControl)
     6716    {
     6717        mBandwidthControl->uninit();
     6718        unconst(mBandwidthControl).setNull();
     6719    }
    66506720
    66516721    for (ULONG slot = 0; slot < RT_ELEMENTS(mNetworkAdapters); slot++)
     
    72697339        mHWData->mIoCacheEnabled = data.ioSettings.fIoCacheEnabled;
    72707340        mHWData->mIoCacheSize = data.ioSettings.ulIoCacheSize;
     7341
     7342        // Bandwidth control
     7343        rc = mBandwidthControl->loadSettings(data.ioSettings);
     7344        if (FAILED(rc)) return rc;
    72717345
    72727346#ifdef VBOX_WITH_GUEST_PROPS
     
    75047578            break;
    75057579
     7580        /* Bandwidth groups are loaded at this point. */
     7581        ComObjPtr<BandwidthGroup> pBwGroup;
     7582
     7583        if (!dev.strBwGroup.isEmpty())
     7584        {
     7585            rc = mBandwidthControl->getBandwidthGroupByName(dev.strBwGroup, pBwGroup, false /* aSetError */);
     7586            if (FAILED(rc))
     7587                return setError(E_FAIL,
     7588                                tr("Device '%s' with unknown bandwidth group '%s' is attached to the virtual machine '%s' ('%s')"),
     7589                                medium->getLocationFull().c_str(),
     7590                                dev.strBwGroup.c_str(),
     7591                                mUserData->s.strName.c_str(),
     7592                                mData->m_strConfigFileFull.c_str());
     7593        }
     7594
    75067595        const Bstr controllerName = aStorageController->getName();
    75077596        ComObjPtr<MediumAttachment> pAttachment;
     
    75147603                               dev.deviceType,
    75157604                               dev.fPassThrough,
    7516                                dev.ulBandwidthLimit);
     7605                               pBwGroup);
    75177606        if (FAILED(rc)) break;
    75187607
     
    83008389        data.ioSettings.ulIoCacheSize = mHWData->mIoCacheSize;
    83018390
     8391        /* BandwidthControl (required) */
     8392        rc = mBandwidthControl->saveSettings(data.ioSettings);
     8393        if (FAILED(rc)) throw rc;
     8394
    83028395        // guest properties
    83038396        data.llGuestProperties.clear();
     
    84178510        MediumAttachment *pAttach = *it;
    84188511        Medium *pMedium = pAttach->getMedium();
     8512        BandwidthGroup *pBwGroup = pAttach->getBandwidthGroup();
    84198513
    84208514        dev.deviceType = pAttach->getType();
     
    84288522                dev.uuid = pMedium->getId();
    84298523            dev.fPassThrough = pAttach->getPassthrough();
     8524        }
     8525
     8526        if (pBwGroup)
     8527        {
     8528            dev.strBwGroup = pBwGroup->getName();
    84308529        }
    84318530
     
    87038802                                  DeviceType_HardDisk,
    87048803                                  true /* aImplicit */,
    8705                                   0 /* No bandwidth limit */);
     8804                                  pAtt->getBandwidthGroup());
    87068805            if (FAILED(rc)) throw rc;
    87078806
     
    93699468        mUSBController->rollback();
    93709469
     9470    if (mBandwidthControl && (mData->flModifications & IsModified_BandwidthControl))
     9471        mBandwidthControl->rollback();
     9472
    93719473    ComPtr<INetworkAdapter> networkAdapters[RT_ELEMENTS(mNetworkAdapters)];
    93729474    ComPtr<ISerialPort> serialPorts[RT_ELEMENTS(mSerialPorts)];
     
    94289530        if (flModifications & IsModified_Storage)
    94299531            that->onStorageControllerChange();
     9532
     9533#if 0
     9534        if (flModifications & IsModified_BandwidthControl)
     9535            that->onBandwidthControlChange();
     9536#endif
    94309537    }
    94319538}
     
    94639570    mAudioAdapter->commit();
    94649571    mUSBController->commit();
     9572    mBandwidthControl->commit();
    94659573
    94669574    for (ULONG slot = 0; slot < RT_ELEMENTS(mNetworkAdapters); slot++)
     
    95939701    mAudioAdapter->copyFrom(aThat->mAudioAdapter);
    95949702    mUSBController->copyFrom(aThat->mUSBController);
     9703    mBandwidthControl->copyFrom(aThat->mBandwidthControl);
    95959704
    95969705    /* create private copies of all controllers */
     
    994610055    }
    994710056
     10057    /* create another bandwidth control object that will be mutable */
     10058    unconst(mBandwidthControl).createObject();
     10059    mBandwidthControl->init(this, aMachine->mBandwidthControl);
     10060
    994810061    /* default is to delete saved state on Saved -> PoweredOff transition */
    994910062    mRemoveSavedState = true;
     
    1120311316
    1120411317/**
     11318 *  @note Locks this object for reading.
     11319 */
     11320HRESULT SessionMachine::onBandwidthGroupChange(IBandwidthGroup *aBandwidthGroup)
     11321{
     11322    LogFlowThisFunc(("\n"));
     11323
     11324    AutoCaller autoCaller(this);
     11325    AssertComRCReturn (autoCaller.rc(), autoCaller.rc());
     11326
     11327    ComPtr<IInternalSessionControl> directControl;
     11328    {
     11329        AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     11330        directControl = mData->mSession.mDirectControl;
     11331    }
     11332
     11333    /* ignore notifications sent after #OnSessionEnd() is called */
     11334    if (!directControl)
     11335        return S_OK;
     11336
     11337    return directControl->OnBandwidthGroupChange(aBandwidthGroup);
     11338}
     11339
     11340/**
    1120511341 *  Returns @c true if this machine's USB controller reports it has a matching
    1120611342 *  filter for the given USB device and @c false otherwise.
  • trunk/src/VBox/Main/Makefile.kmk

    r34416 r34587  
    319319        DisplayPNGUtil.cpp \
    320320        DisplayResampleImage.cpp \
     321        BandwidthControlImpl.cpp \
     322        BandwidthGroupImpl.cpp \
    321323        $(VBOX_AUTOGEN_EVENT_CPP) \
    322324        VRDEServerImpl.cpp \
  • trunk/src/VBox/Main/MediumAttachmentImpl.cpp

    r33078 r34587  
    1919#include "MachineImpl.h"
    2020#include "MediumImpl.h"
     21#include "BandwidthGroupImpl.h"
    2122#include "Global.h"
    2223
     24#include "AutoStateDep.h"
    2325#include "AutoCaller.h"
    2426#include "Logging.h"
     
    3941          type(DeviceType_Null),
    4042          fPassthrough(false),
    41           fImplicit(false),
    42           mBandwidthLimit(0)
     43          fImplicit(false)
    4344    { }
    4445
    4546    ComObjPtr<Medium>   pMedium;
     47    ComObjPtr<BandwidthGroup> pBwGroup;
    4648    /* Since MediumAttachment is not a first class citizen when it
    4749     * comes to managing settings, having a reference to the storage
     
    5557    bool                fPassthrough;
    5658    bool                fImplicit;
    57     ULONG               mBandwidthLimit;
    5859};
    5960
     
    108109                               DeviceType_T aType,
    109110                               bool aPassthrough,
    110                                ULONG aBandwidthLimit)
     111                               BandwidthGroup *aBandwidthGroup)
    111112{
    112113    LogFlowThisFuncEnter();
     
    126127    m->bd.allocate();
    127128    m->bd->pMedium = aMedium;
     129    if (aBandwidthGroup)
     130        aBandwidthGroup->reference();
     131    m->bd->pBwGroup = aBandwidthGroup;
    128132    unconst(m->bd->bstrControllerName) = aControllerName;
    129133    unconst(m->bd->lPort)   = aPort;
     
    135139     * associated with them. Implicit diff image creation happens later. */
    136140    m->bd->fImplicit = false;
    137 
    138     m->bd->mBandwidthLimit = aBandwidthLimit;
    139141
    140142    /* Confirm a successful initialization when it's the case */
     
    278280}
    279281
    280 STDMETHODIMP MediumAttachment::COMGETTER(BandwidthLimit) (ULONG *aLimit)
    281 {
    282     CheckComArgOutPointerValid(aLimit);
     282STDMETHODIMP MediumAttachment::COMGETTER(BandwidthGroup) (IBandwidthGroup **aBwGroup)
     283{
     284    CheckComArgOutPointerValid(aBwGroup);
    283285
    284286    AutoCaller autoCaller(this);
     
    287289    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    288290
    289     *aLimit = m->bd->mBandwidthLimit;
    290     return S_OK;
    291 }
    292 
    293 STDMETHODIMP MediumAttachment::COMSETTER(BandwidthLimit) (ULONG aLimit)
    294 {
    295     AutoCaller autoCaller(this);
    296     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    297 
    298     /* the machine doesn't need to be mutable */
    299 
    300     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    301 
    302     if (aLimit != m->bd->mBandwidthLimit)
    303     {
    304         m->bd.backup();
    305         m->bd->mBandwidthLimit = aLimit;
    306 
    307         /* todo: not all storage attachments will support this. */
    308     }
     291    m->bd->pBwGroup.queryInterfaceTo(aBwGroup);
     292
    309293    return S_OK;
    310294}
     
    386370    AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
    387371    return m->bd->fPassthrough;
     372}
     373
     374const ComObjPtr<BandwidthGroup>& MediumAttachment::getBandwidthGroup() const
     375{
     376    return m->bd->pBwGroup;
    388377}
    389378
     
    417406}
    418407
     408void MediumAttachment::updateBandwidthGroup(const ComObjPtr<BandwidthGroup> &aBandwidthGroup)
     409{
     410    Assert(isWriteLockOnCurrentThread());
     411
     412    m->bd.backup();
     413    if (!aBandwidthGroup.isNull())
     414        aBandwidthGroup->reference();
     415
     416    if (!m->bd->pBwGroup.isNull())
     417    {
     418        m->bd->pBwGroup->release();
     419    }
     420    m->bd->pBwGroup = aBandwidthGroup;
     421}
     422
  • trunk/src/VBox/Main/SessionImpl.cpp

    r33952 r34587  
    704704
    705705    return mConsole->onShowWindow(aCheck, aCanShow, aWinId);
     706}
     707
     708STDMETHODIMP Session::OnBandwidthGroupChange(IBandwidthGroup *aBandwidthGroup)
     709{
     710    LogFlowThisFunc(("\n"));
     711
     712    AutoCaller autoCaller(this);
     713    AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
     714
     715    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     716    AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
     717    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
     718
     719    return mConsole->onBandwidthGroupChange(aBandwidthGroup);
    706720}
    707721
  • trunk/src/VBox/Main/SnapshotImpl.cpp

    r33921 r34587  
    10321032        mParallelPorts[slot]->initCopy(this, mPeer->mParallelPorts[slot]);
    10331033    }
     1034
     1035    unconst(mBandwidthControl).createObject();
     1036    mBandwidthControl->initCopy(this, mPeer->mBandwidthControl);
    10341037
    10351038    /* Confirm a successful initialization when it's the case */
     
    11231126        mParallelPorts[slot]->init(this, slot);
    11241127    }
     1128
     1129    unconst(mBandwidthControl).createObject();
     1130    mBandwidthControl->init(this);
    11251131
    11261132    /* load hardware and harddisk settings */
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r34574 r34587  
    34763476  <interface
    34773477    name="IMachine" extends="$unknown"
    3478     uuid="711cbb73-75af-463c-af17-8b7860c01fe8"
     3478    uuid="662c175e-a69d-40b8-a77a-1d719d0ab062"
    34793479    wsmap="managed"
    34803480    >
     
    40694069    </attribute>
    40704070
     4071    <attribute name="bandwidthControl" type="IBandwidthControl" readonly="yes">
     4072      <desc>
     4073        Bandwidth control manager.
     4074      </desc>
     4075    </attribute>
     4076
    40714077    <attribute name="pciDeviceAssignments" type="IPciDeviceAttachment" readonly="yes" safearray="yes">
    40724078      <desc>Array of PCI devices assigned to this machine, to get list of all PCI devices
     
    45194525      <param name="passthrough" type="boolean" dir="in">
    45204526        <desc>New value for the passthrough setting.</desc>
     4527      </param>
     4528    </method>
     4529
     4530    <method name="setBandwidthGroupForDevice">
     4531      <desc>
     4532        Sets the passthrough mode of an existing DVD device. Changing the
     4533        setting while the VM is running is forbidden. The setting is only used
     4534        if at VM start the device is configured as a host DVD drive, in all
     4535        other cases it is ignored. The device must already exist; see
     4536        <link to="IMachine::attachDevice"/> for how to attach a new device.
     4537
     4538        The @a controllerPort and @a device parameters specify the device slot and
     4539        have have the same meaning as with <link to="IMachine::attachDevice" />.
     4540
     4541        <result name="E_INVALIDARG">
     4542          SATA device, SATA port, IDE port or IDE slot out of range.
     4543        </result>
     4544        <result name="VBOX_E_INVALID_OBJECT_STATE">
     4545          Attempt to modify an unregistered virtual machine.
     4546        </result>
     4547        <result name="VBOX_E_INVALID_VM_STATE">
     4548          Invalid machine state.
     4549        </result>
     4550
     4551      </desc>
     4552      <param name="name" type="wstring" dir="in">
     4553        <desc>Name of the storage controller.</desc>
     4554      </param>
     4555      <param name="controllerPort" type="long" dir="in">
     4556        <desc>Storage controller port.</desc>
     4557      </param>
     4558      <param name="device" type="long" dir="in">
     4559        <desc>Device slot in the given port.</desc>
     4560      </param>
     4561      <param name="bandwidthGroup" type="IBandwidthGroup" dir="in">
     4562        <desc>New value for the bandwidth group or NULL for no group.</desc>
    45214563      </param>
    45224564    </method>
     
    88298871  <interface
    88308872    name="IMediumAttachment" extends="$unknown"
    8831     uuid="c29452cc-ca72-404b-9261-cfc514f1e412"
     8873    uuid="aa4b4840-934f-454d-9a28-23e8f4235edf"
    88328874    wsmap="struct"
    88338875    >
     
    88828924    </attribute>
    88838925
    8884     <attribute name="bandwidthLimit" type="unsigned long">
    8885       <desc>
    8886         Maximum throughput allowed for this medium attachment, in units of 1 mbps.
    8887         A zero value means uncapped/unlimited.
    8888       </desc>
     8926    <attribute name="bandwidthGroup" type="IBandwidthGroup" readonly="yes">
     8927      <desc>The bandwidth group this medium attachment is assigned to.</desc>
    88898928    </attribute>
    88908929
     
    1283512874  <interface
    1283612875    name="IInternalSessionControl" extends="$unknown"
    12837     uuid="06ef98a7-f7c0-45ba-bf99-9aca7a4d5530"
     12876    uuid="a2fbf834-149d-41da-ae52-0dc3b0f032b3"
    1283812877    internal="yes"
    1283912878    wsmap="suppress"
     
    1313613175      <param name="canShow" type="boolean" dir="out"/>
    1313713176      <param name="winId" type="long long" dir="out"/>
     13177    </method>
     13178
     13179    <method name="onBandwidthGroupChange">
     13180      <desc>
     13181        Notification when one of the bandwidth groups change.
     13182      </desc>
     13183      <param name="bandwidthGroup" type="IBandwidthGroup" dir="in">
     13184        <desc>The bandwidth group which changed.</desc>
     13185      </param>
    1313813186    </method>
    1313913187
     
    1441914467
    1442014468  <!--
     14469  // BandwidthGroupType
     14470  /////////////////////////////////////////////////////////////////////////
     14471  -->
     14472  <enum
     14473     name="BandwidthGroupType"
     14474     uuid="1d92b67d-dc69-4be9-ad4c-93a01e1e0c8e">
     14475
     14476    <desc>
     14477      Type of a bandwidth control group.
     14478    </desc>
     14479
     14480    <const name="Null" value="0">
     14481      <desc>
     14482        Null type, must be first.
     14483      </desc>
     14484    </const>
     14485
     14486    <const name="Disk" value="1">
     14487      <desc>
     14488        The bandwidth group controls disk I/O.
     14489      </desc>
     14490    </const>
     14491
     14492    <const name="Network" value="2">
     14493      <desc>
     14494        The bandwidth group controls network I/O.
     14495      </desc>
     14496    </const>
     14497
     14498  </enum>
     14499
     14500  <!--
     14501  // IBandwidthGroup
     14502  /////////////////////////////////////////////////////////////////////////
     14503  -->
     14504  <interface
     14505    name="IBandwidthGroup" extends="$unknown"
     14506    uuid="badea2d7-0261-4146-89f0-6a57cc34833d"
     14507    wsmap="managed"
     14508    >
     14509    <desc>Represents one bandwidth group.</desc>
     14510
     14511    <attribute name="name" type="wstring" readonly="yes">
     14512      <desc>Name of the group.</desc>
     14513    </attribute>
     14514
     14515    <attribute name="type" type="BandwidthGroupType" readonly="yes">
     14516      <desc>Type of the group.</desc>
     14517    </attribute>
     14518
     14519    <attribute name="reference" type="unsigned long" readonly="yes">
     14520      <desc>How many devices/medium attachements use this group.</desc>
     14521    </attribute>
     14522
     14523    <attribute name="maxMbPerSec" type="unsigned long">
     14524      <desc>The maximum number of MB which can be transfered by all
     14525        entities attached to this group during one second.</desc>
     14526    </attribute>
     14527
     14528  </interface>
     14529
     14530  <!--
     14531  // IBandwidthControl
     14532  /////////////////////////////////////////////////////////////////////////
     14533  -->
     14534  <interface
     14535    name="IBandwidthControl" extends="$unknown"
     14536    uuid="d0a24db0-f756-11df-98cf-0800200c9a66"
     14537    wsmap="managed"
     14538    >
     14539    <desc>
     14540      Controls the bandwidth groups of one machine used to cap I/O done by a VM.
     14541      This includes network and disk I/O.
     14542    </desc>
     14543
     14544    <attribute name="numGroups" type="unsigned long" readonly="yes">
     14545      <desc>
     14546        The current number of existing bandwidth groups managed.
     14547      </desc>
     14548    </attribute>
     14549
     14550    <method name="CreateBandwidthGroup">
     14551      <desc>
     14552        Creates a new bandwidth group.
     14553      </desc>
     14554
     14555      <param name="name" type="wstring" dir="in">
     14556        <desc>Name of the bandwidth group.</desc>
     14557      </param>
     14558      <param name="type" type="BandwidthGroupType" dir="in">
     14559        <desc>The type of the bandwidth group (network or disk).</desc>
     14560      </param>
     14561      <param name="maxBytesPerSec" type="unsigned long" dir="in">
     14562        <desc>The maximum number of bytes which can be transfered by all
     14563          entities attached to this group during one second.</desc>
     14564      </param>
     14565    </method>
     14566
     14567    <method name="DeleteBandwidthGroup">
     14568      <desc>
     14569        Deletes a new bandwidth group.
     14570      </desc>
     14571
     14572      <param name="name" type="wstring" dir="in">
     14573        <desc>Name of the bandwidth group to delete.</desc>
     14574      </param>
     14575    </method>
     14576
     14577    <method name="GetBandwidthGroup" const="yes">
     14578      <desc>
     14579        Get a bandwidth group by name.
     14580      </desc>
     14581
     14582      <param name="name" type="wstring" dir="in">
     14583        <desc>Name of the bandwidth group to get.</desc>
     14584      </param>
     14585      <param name="bandwidthGroup" type="IBandwidthGroup" dir="return">
     14586        <desc>Where to store the bandwidth group on success.</desc>
     14587      </param>
     14588    </method>
     14589
     14590    <method name="GetAllBandwidthGroups" const="yes">
     14591      <desc>
     14592        Get all managed bandwidth groups.
     14593      </desc>
     14594
     14595      <param name="bandwidthGroups" type="IBandwidthGroup" dir="return" safearray="yes">
     14596        <desc>The array of managed bandwidth groups.</desc>
     14597      </param>
     14598    </method>
     14599  </interface>
     14600
     14601  <!--
    1442114602  // IVirtualBoxClient
    1442214603  /////////////////////////////////////////////////////////////////////////
     
    1446314644  <enum
    1446414645    name="VBoxEventType"
    14465     uuid="BA0F90B2-3F41-4222-840D-EDD5055476A8"
     14646    uuid="c9412a17-c1e1-46db-b4b7-18de9c967e85"
    1446614647    >
    1446714648
     
    1470614887      </desc>
    1470714888    </const>
     14889    <const name="OnBandwidthGroupChanged" value="69">
     14890      <desc>
     14891        See <link to="IBandwidthGroupChangedEvent">IBandwidthGroupChangedEvent</link>.
     14892      </desc>
     14893    </const>
    1470814894
    1470914895    <!-- Last event marker -->
    14710     <const name="Last" value="69">
     14896    <const name="Last" value="70">
    1471114897      <desc>
    1471214898        Must be last event, used for iterations and structures relying on numerical event values.
     
    1600016186  </interface>
    1600116187
     16188  <interface
     16189    name="IBandwidthGroupChangedEvent" extends="IEvent"
     16190    uuid="334df94a-7556-4cbc-8c04-043096b02d82"
     16191    wsmap="managed" autogen="VBoxEvent" id="OnBandwidthGroupChanged"
     16192    >
     16193    <desc>
     16194      Notification when one of the bandwidth groups changed
     16195    </desc>
     16196    <attribute name="bandwidthGroup" type="IBandwidthGroup" readonly="yes">
     16197      <desc>
     16198        The changed bandwidth group.
     16199      </desc>
     16200    </attribute>
     16201  </interface>
     16202
    1600216203  <module name="VBoxSVC" context="LocalServer">
    1600316204    <class name="VirtualBox" uuid="B1A7A4F2-47B9-4A1E-82B2-07CCD5323C3F"
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r34434 r34587  
    191191    HRESULT onUSBDeviceAttach(IUSBDevice *aDevice, IVirtualBoxErrorInfo *aError, ULONG aMaskedIfs);
    192192    HRESULT onUSBDeviceDetach(IN_BSTR aId, IVirtualBoxErrorInfo *aError);
     193    HRESULT onBandwidthGroupChange(IBandwidthGroup *aBandwidthGroup);
    193194    HRESULT getGuestProperty(IN_BSTR aKey, BSTR *aValue, LONG64 *aTimestamp, BSTR *aFlags);
    194195    HRESULT setGuestProperty(IN_BSTR aKey, IN_BSTR aValue, IN_BSTR aFlags);
     
    482483                     unsigned uMergeSource,
    483484                     unsigned uMergeTarget,
     485                     const char *pcszBwGroup,
    484486                     IMedium *pMedium,
    485487                     MachineState_T aMachineState,
  • trunk/src/VBox/Main/include/MachineImpl.h

    r34331 r34587  
    3232#include "BIOSSettingsImpl.h"
    3333#include "StorageControllerImpl.h"          // required for MachineImpl.h to compile on Windows
     34#include "BandwidthControlImpl.h"
    3435#include "VBox/settings.h"
    3536#ifdef VBOX_WITH_RESOURCE_USAGE_API
     
    468469    STDMETHOD(DetachDevice)(IN_BSTR aControllerName, LONG aControllerPort, LONG aDevice);
    469470    STDMETHOD(PassthroughDevice)(IN_BSTR aControllerName, LONG aControllerPort, LONG aDevice, BOOL aPassthrough);
     471    STDMETHOD(SetBandwidthGroupForDevice)(IN_BSTR aControllerName, LONG aControllerPort,
     472                                          LONG aDevice, IBandwidthGroup *aBandwidthGroup);
    470473    STDMETHOD(MountMedium)(IN_BSTR aControllerName, LONG aControllerPort,
    471474                           LONG aDevice, IMedium *aMedium, BOOL aForce);
     
    523526    STDMETHOD(DetachHostPciDevice(LONG hostAddress));
    524527    STDMETHOD(COMGETTER(PciDeviceAssignments))(ComSafeArrayOut(IPciDeviceAttachment *, aAssignments));
     528    STDMETHOD(COMGETTER(BandwidthControl))(IBandwidthControl **aBandwidthControl);
    525529    // public methods only for internal purposes
    526530
     
    610614        IsModified_BIOS                 = 0x0200,
    611615        IsModified_SharedFolders        = 0x0400,
    612         IsModified_Snapshots            = 0x0800
     616        IsModified_Snapshots            = 0x0800,
     617        IsModified_BandwidthControl     = 0x1000
    613618    };
    614619
     
    628633    virtual HRESULT onMediumChange(IMediumAttachment * /* mediumAttachment */, BOOL /* force */) { return S_OK; }
    629634    virtual HRESULT onSharedFolderChange() { return S_OK; }
     635    virtual HRESULT onBandwidthGroupChange(IBandwidthGroup */* aBandwidthGroup */) { return S_OK; }
    630636
    631637    HRESULT saveRegistryEntry(settings::MachineRegistryEntry &data);
     
    860866    const ComObjPtr<BIOSSettings>   mBIOSSettings;
    861867    const ComObjPtr<NetworkAdapter> mNetworkAdapters[SchemaDefs::NetworkAdapterCount];
     868    const ComObjPtr<BandwidthControl> mBandwidthControl;
    862869
    863870    typedef std::list< ComObjPtr<StorageController> > StorageControllerList;
     
    980987                              IVirtualBoxErrorInfo *aError);
    981988    HRESULT onSharedFolderChange();
     989    HRESULT onBandwidthGroupChange(IBandwidthGroup *aBandwidthGroup);
    982990
    983991    bool hasMatchingUSBFilter(const ComObjPtr<HostUSBDevice> &aDevice, ULONG *aMaskedIfs);
  • trunk/src/VBox/Main/include/MediumAttachmentImpl.h

    r33078 r34587  
    2020
    2121#include "VirtualBoxBase.h"
     22#include "BandwidthGroupImpl.h"
    2223
    2324class ATL_NO_VTABLE MediumAttachment :
     
    4950                 DeviceType_T aType,
    5051                 bool fPassthrough,
    51                  ULONG aBandwidthLimit);
     52                 BandwidthGroup *aBandwidthGroup);
    5253    void uninit();
    5354
     
    6263    STDMETHOD(COMGETTER(Type))(DeviceType_T *aType);
    6364    STDMETHOD(COMGETTER(Passthrough))(BOOL *aPassthrough);
    64     STDMETHOD(COMGETTER(BandwidthLimit))(ULONG *aLimit);
    65     STDMETHOD(COMSETTER(BandwidthLimit))(ULONG aLimit);
     65    STDMETHOD(COMGETTER(BandwidthGroup))(IBandwidthGroup **aBwGroup);
    6666
    6767    // public internal methods
     
    8080    DeviceType_T getType() const;
    8181    bool getPassthrough() const;
     82    const ComObjPtr<BandwidthGroup>& getBandwidthGroup() const;
    8283
    8384    bool matches(CBSTR aControllerName, LONG aPort, LONG aDevice);
     
    8889    /** Must be called from under this object's write lock. */
    8990    void updatePassthrough(bool aPassthrough);
     91
     92    /** Must be called from under this object's write lock. */
     93    void updateBandwidthGroup(const ComObjPtr<BandwidthGroup> &aBandwidthGroup);
    9094
    9195    /** Get a unique and somewhat descriptive name for logging. */
  • trunk/src/VBox/Main/include/SessionImpl.h

    r33952 r34587  
    9797    STDMETHOD(OnUSBDeviceDetach)(IN_BSTR aId, IVirtualBoxErrorInfo *aError);
    9898    STDMETHOD(OnShowWindow)(BOOL aCheck, BOOL *aCanShow, LONG64 *aWinId);
     99    STDMETHOD(OnBandwidthGroupChange)(IBandwidthGroup *aBandwidthGroup);
    99100    STDMETHOD(AccessGuestProperty)(IN_BSTR aName, IN_BSTR aValue, IN_BSTR aFlags,
    100101                                   BOOL aIsSetter, BSTR *aRetValue, LONG64 *aRetTimestamp, BSTR *aRetFlags);
  • trunk/src/VBox/Main/xml/Settings.cpp

    r34574 r34587  
    16341634                  && (llGuestProperties         == h.llGuestProperties)
    16351635                  && (strNotificationPatterns   == h.strNotificationPatterns)
     1636                  && (ioSettings                == h.ioSettings)
    16361637                )
    16371638            );
     
    16521653                  && (uuid                      == a.uuid)
    16531654                  && (strHostDriveSrc           == a.strHostDriveSrc)
    1654                   && (ulBandwidthLimit          == a.ulBandwidthLimit)
     1655                  && (strBwGroup                == a.strBwGroup)
    16551656                )
    16561657           );
     
    26562657        else if (pelmHwChild->nameEquals("IO"))
    26572658        {
     2659            const xml::ElementNode *pelmBwGroups;
    26582660            const xml::ElementNode *pelmIoChild;
    26592661
     
    26622664                pelmIoChild->getAttributeValue("enabled", hw.ioSettings.fIoCacheEnabled);
    26632665                pelmIoChild->getAttributeValue("size", hw.ioSettings.ulIoCacheSize);
     2666            }
     2667
     2668            if ((pelmBwGroups = pelmHwChild->findChildElement("BandwidthGroups")))
     2669            {
     2670                xml::NodesLoop nl2(*pelmBwGroups, "BandwidthGroup");
     2671                const xml::ElementNode *pelmBandwidthGroup;
     2672                while ((pelmBandwidthGroup = nl2.forAllNodes()))
     2673                {
     2674                    BandwidthGroup gr;
     2675                    Utf8Str strTemp;
     2676
     2677                    pelmBandwidthGroup->getAttributeValue("name", gr.strName);
     2678
     2679                    if (pelmBandwidthGroup->getAttributeValue("type", strTemp))
     2680                    {
     2681                        if (strTemp == "Disk")
     2682                            gr.enmType = BandwidthGroupType_Disk;
     2683                        else if (strTemp == "Network")
     2684                            gr.enmType = BandwidthGroupType_Network;
     2685                        else
     2686                            throw ConfigFileError(this, pelmBandwidthGroup, N_("Invalid value '%s' in BandwidthGroup/@type attribute"), strTemp.c_str());
     2687                    }
     2688                    else
     2689                        throw ConfigFileError(this, pelmBandwidthGroup, N_("Missing BandwidthGroup/@type attribute"));
     2690
     2691                    pelmBandwidthGroup->getAttributeValue("maxMbPerSec", gr.cMaxMbPerSec);
     2692                    hw.ioSettings.llBandwidthGroups.push_back(gr);
     2693                }
    26642694            }
    26652695        }
     
    28782908                    throw ConfigFileError(this, pelmImage, N_("Required AttachedDevice/@device attribute is missing"));
    28792909
    2880                 pelmAttached->getAttributeValue("bandwidthLimit", att.ulBandwidthLimit);
     2910                pelmAttached->getAttributeValue("bandwidthGroup", att.strBwGroup);
    28812911                sctl.llAttachedDevices.push_back(att);
    28822912            }
     
    37603790        xml::ElementNode *pelmIo = pelmHardware->createChild("IO");
    37613791        xml::ElementNode *pelmIoCache;
    3762         xml::ElementNode *pelmIoBandwidth;
    37633792
    37643793        pelmIoCache = pelmIo->createChild("IoCache");
    37653794        pelmIoCache->setAttribute("enabled", hw.ioSettings.fIoCacheEnabled);
    37663795        pelmIoCache->setAttribute("size", hw.ioSettings.ulIoCacheSize);
    3767         pelmIoBandwidth = pelmIo->createChild("IoBandwidth");
     3796
     3797        if (m->sv >= SettingsVersion_v1_11)
     3798        {
     3799            xml::ElementNode *pelmBandwidthGroups = pelmIo->createChild("BandwidthGroups");
     3800            for (BandwidthGroupList::const_iterator it = hw.ioSettings.llBandwidthGroups.begin();
     3801                 it != hw.ioSettings.llBandwidthGroups.end();
     3802                 ++it)
     3803            {
     3804                const BandwidthGroup &gr = *it;
     3805                const char *pcszType;
     3806                xml::ElementNode *pelmThis = pelmBandwidthGroups->createChild("BandwidthGroup");
     3807                pelmThis->setAttribute("name", gr.strName);
     3808                switch (gr.enmType)
     3809                {
     3810                    case BandwidthGroupType_Network: pcszType = "Network"; break;
     3811                    default: /* BandwidthGrouptype_Disk */ pcszType = "Disk"; break;
     3812                }
     3813                pelmThis->setAttribute("type", pcszType);
     3814                pelmThis->setAttribute("maxMbPerSec", gr.cMaxMbPerSec);
     3815            }
     3816        }
    37683817    }
    37693818
     
    40074056            pelmDevice->setAttribute("device", att.lDevice);
    40084057
    4009             if (att.ulBandwidthLimit)
    4010                 pelmDevice->setAttribute("bandwidthLimit", att.ulBandwidthLimit);
     4058            if (att.strBwGroup.length())
     4059                pelmDevice->setAttribute("bandwidthGroup", att.strBwGroup);
    40114060
    40124061            // attached image, if any
     
    43254374    {
    43264375        // VirtualBox 4.0 adds HD audio, CPU priorities, fault tolerance,
    4327         // per-machine media registries, VRDE and JRockitVE.
     4376        // per-machine media registries, VRDE, JRockitVE and bandwidth gorups.
    43284377        if (    hardwareMachine.audioAdapter.controllerType == AudioControllerType_HDA
    43294378             || hardwareMachine.ulCpuExecutionCap != 100
     
    43384387             || !hardwareMachine.vrdeSettings.strAuthLibrary.isEmpty()
    43394388             || machineUserData.strOsType == "JRockitVE"
     4389             || hardwareMachine.ioSettings.llBandwidthGroups.size()
    43404390           )
    43414391            m->sv = SettingsVersion_v1_11;
     
    44374487                // Bandwidth limitations are new in VirtualBox 4.0 (1.11)
    44384488                if (    (m->sv < SettingsVersion_v1_11)
    4439                      && (att.ulBandwidthLimit != 0)
     4489                     && (att.strBwGroup.length() != 0)
    44404490                   )
    44414491                {
  • trunk/src/VBox/Main/xpcom/server.cpp

    r33842 r34587  
    9595# include <ExtPackManagerImpl.h>
    9696#endif
     97#include <BandwidthGroupImpl.h>
     98#include <BandwidthControlImpl.h>
    9799
    98100/* implement nsISupports parts of our objects with support for nsIClassInfo */
     
    211213NS_IMPL_THREADSAFE_ISUPPORTS1_CI(ExtPackManager, IExtPackManager)
    212214#endif
     215
     216NS_DECL_CLASSINFO(BandwidthGroup)
     217NS_IMPL_THREADSAFE_ISUPPORTS1_CI(BandwidthGroup, IBandwidthGroup)
     218
     219NS_DECL_CLASSINFO(BandwidthControl)
     220NS_IMPL_THREADSAFE_ISUPPORTS1_CI(BandwidthControl, IBandwidthControl)
    213221
    214222////////////////////////////////////////////////////////////////////////////////
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