VirtualBox

Ignore:
Timestamp:
Jan 28, 2018 8:53:14 PM (7 years ago)
Author:
vboxsync
Message:

Main,FE/VBoxManage: Allow changing the serial port attachment type during runtime

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r70753 r70766  
    50795079}
    50805080
     5081
     5082/**
     5083 * Performs the Serial Port attachment change in EMT.
     5084 *
     5085 * @returns VBox status code.
     5086 *
     5087 * @param   pThis               Pointer to the Console object.
     5088 * @param   pUVM                The VM handle.
     5089 * @param   pSerialPort         The serial port whose attachment needs to be changed
     5090 *
     5091 * @thread  EMT
     5092 * @note Locks the Console object for writing.
     5093 * @note The VM must not be running.
     5094 */
     5095DECLCALLBACK(int) Console::i_changeSerialPortAttachment(Console *pThis, PUVM pUVM,
     5096                                                        ISerialPort *pSerialPort)
     5097{
     5098    LogFlowFunc(("pThis=%p pUVM=%p pSerialPort=%p\n", pThis, pUVM, pSerialPort));
     5099
     5100    AssertReturn(pThis, VERR_INVALID_PARAMETER);
     5101
     5102    AutoCaller autoCaller(pThis);
     5103    AssertComRCReturn(autoCaller.rc(), VERR_ACCESS_DENIED);
     5104
     5105    AutoWriteLock alock(pThis COMMA_LOCKVAL_SRC_POS);
     5106
     5107    /*
     5108     * Check the VM for correct state.
     5109     */
     5110    VMSTATE enmVMState = VMR3GetStateU(pUVM);
     5111    AssertReturn(enmVMState == VMSTATE_SUSPENDED, VERR_INVALID_STATE);
     5112
     5113    HRESULT hrc = S_OK;
     5114    int rc = VINF_SUCCESS;
     5115    ULONG ulSlot;
     5116    hrc = pSerialPort->COMGETTER(Slot)(&ulSlot);
     5117    if (SUCCEEDED(hrc))
     5118    {
     5119        /* Check whether the port mode changed and act accordingly. */
     5120        Assert(ulSlot < 4);
     5121
     5122        PortMode_T eHostMode;
     5123        hrc = pSerialPort->COMGETTER(HostMode)(&eHostMode);
     5124        if (SUCCEEDED(hrc))
     5125        {
     5126            PCFGMNODE pInst = CFGMR3GetChildF(CFGMR3GetRootU(pUVM), "Devices/serial/%d/", ulSlot);
     5127            AssertRelease(pInst);
     5128
     5129            /* Remove old driver. */
     5130            if (pThis->m_aeSerialPortMode[ulSlot] != PortMode_Disconnected)
     5131            {
     5132                rc = PDMR3DeviceDetach(pUVM, "serial", ulSlot, 0, 0);
     5133                PCFGMNODE pLunL0 = CFGMR3GetChildF(pInst, "LUN#0");
     5134                CFGMR3RemoveNode(pLunL0);
     5135            }
     5136
     5137            if (RT_SUCCESS(rc))
     5138            {
     5139                BOOL fServer;
     5140                Bstr bstrPath;
     5141                hrc = pSerialPort->COMGETTER(Server)(&fServer);
     5142                if (SUCCEEDED(hrc))
     5143                    hrc = pSerialPort->COMGETTER(Path)(bstrPath.asOutParam());
     5144
     5145                /* Configure new driver. */
     5146                if (   SUCCEEDED(hrc)
     5147                    && eHostMode != PortMode_Disconnected)
     5148                {
     5149                    rc = pThis->i_configSerialPort(pInst, eHostMode, Utf8Str(bstrPath).c_str(), RT_BOOL(fServer));
     5150                    if (RT_SUCCESS(rc))
     5151                    {
     5152                        /*
     5153                         * Attach the driver.
     5154                         */
     5155                        PPDMIBASE pBase;
     5156                        rc = PDMR3DeviceAttach(pUVM, "serial", ulSlot, 0, 0, &pBase);
     5157
     5158                        CFGMR3Dump(pInst);
     5159                    }
     5160                }
     5161            }
     5162        }
     5163    }
     5164
     5165    if (RT_SUCCESS(rc) && FAILED(hrc))
     5166        rc = VERR_INTERNAL_ERROR;
     5167
     5168    LogFlowFunc(("Returning %Rrc\n", rc));
     5169    return rc;
     5170}
     5171
     5172
    50815173/**
    50825174 * Called by IInternalSessionControl::OnSerialPortChange().
     
    50895181    AssertComRCReturnRC(autoCaller.rc());
    50905182
    5091     fireSerialPortChangedEvent(mEventSource, aSerialPort);
     5183    HRESULT hrc = S_OK;
     5184
     5185    /* don't trigger audio changes if the VM isn't running */
     5186    SafeVMPtrQuiet ptrVM(this);
     5187    if (ptrVM.isOk())
     5188    {
     5189        ULONG ulSlot;
     5190        BOOL fEnabled;
     5191        hrc = aSerialPort->COMGETTER(Slot)(&ulSlot);
     5192        if (SUCCEEDED(hrc))
     5193            hrc = aSerialPort->COMGETTER(Enabled)(&fEnabled);
     5194        if (SUCCEEDED(hrc) && fEnabled)
     5195        {
     5196            /* Check whether the port mode changed and act accordingly. */
     5197            Assert(ulSlot < 4);
     5198
     5199            PortMode_T eHostMode;
     5200            hrc = aSerialPort->COMGETTER(HostMode)(&eHostMode);
     5201            if (m_aeSerialPortMode[ulSlot] != eHostMode)
     5202            {
     5203                /*
     5204                 * Suspend the VM first.
     5205                 */
     5206                bool fResume = false;
     5207                HRESULT hr = i_suspendBeforeConfigChange(ptrVM.rawUVM(), NULL, &fResume);
     5208                if (FAILED(hr))
     5209                    return hr;
     5210
     5211                /*
     5212                 * Call worker in EMT, that's faster and safer than doing everything
     5213                 * using VM3ReqCallWait.
     5214                 */
     5215                int rc = VMR3ReqCallWaitU(ptrVM.rawUVM(), 0 /*idDstCpu*/,
     5216                                          (PFNRT)i_changeSerialPortAttachment, 6,
     5217                                          this, ptrVM.rawUVM(), aSerialPort);
     5218
     5219                if (fResume)
     5220                    i_resumeAfterConfigChange(ptrVM.rawUVM());
     5221                if (RT_SUCCESS(rc))
     5222                    m_aeSerialPortMode[ulSlot] = eHostMode;
     5223                else
     5224                    hrc = setError(E_FAIL,
     5225                                   tr("Failed to change the serial port attachment (%Rrc)"), rc);
     5226            }
     5227        }
     5228    }
     5229
     5230    if (SUCCEEDED(hrc))
     5231        fireSerialPortChangedEvent(mEventSource, aSerialPort);
    50925232
    50935233    LogFlowThisFunc(("Leaving rc=%#x\n", S_OK));
    5094     return S_OK;
     5234    return hrc;
    50955235}
    50965236
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