VirtualBox

Changeset 70766 in vbox for trunk/src/VBox/Main/src-client


Ignore:
Timestamp:
Jan 28, 2018 8:53:14 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
120539
Message:

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

Location:
trunk/src/VBox/Main/src-client
Files:
2 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
  • trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp

    r70712 r70766  
    13841384        PCFGMNODE pLunL0 = NULL;        /* /Devices/Dev/0/LUN#0/ */
    13851385        PCFGMNODE pLunL1 = NULL;        /* /Devices/Dev/0/LUN#0/AttachedDriver/ */
    1386         PCFGMNODE pLunL2 = NULL;        /* /Devices/Dev/0/LUN#0/AttachedDriver/Config/ */
    13871386        PCFGMNODE pBiosCfg = NULL;      /* /Devices/pcbios/0/Config/ */
    13881387        PCFGMNODE pNetBootCfg = NULL;   /* /Devices/pcbios/0/Config/NetBoot/ */
     
    26612660            }
    26622661            if (!fEnabledSerPort)
     2662            {
     2663                m_aeSerialPortMode[ulInstance] = PortMode_Disconnected;
    26632664                continue;
     2665            }
    26642666
    26652667            InsertConfigNode(pDev, Utf8StrFmt("%u", ulInstance).c_str(), &pInst);
     
    26812683            PortMode_T eHostMode;
    26822684            hrc = serialPort->COMGETTER(HostMode)(&eHostMode);                              H();
     2685
     2686            m_aeSerialPortMode[ulInstance] = eHostMode;
    26832687            if (eHostMode != PortMode_Disconnected)
    26842688            {
    2685                 InsertConfigNode(pInst,     "LUN#0", &pLunL0);
    2686                 if (eHostMode == PortMode_HostPipe)
    2687                 {
    2688                     InsertConfigString(pLunL0,  "Driver", "Char");
    2689                     InsertConfigNode(pLunL0,    "AttachedDriver", &pLunL1);
    2690                     InsertConfigString(pLunL1,  "Driver", "NamedPipe");
    2691                     InsertConfigNode(pLunL1,    "Config", &pLunL2);
    2692                     InsertConfigString(pLunL2,  "Location", bstr);
    2693                     InsertConfigInteger(pLunL2, "IsServer", fServer);
    2694                 }
    2695                 else if (eHostMode == PortMode_HostDevice)
    2696                 {
    2697                     InsertConfigString(pLunL0,  "Driver", "Host Serial");
    2698                     InsertConfigNode(pLunL0,    "Config", &pLunL1);
    2699                     InsertConfigString(pLunL1,  "DevicePath", bstr);
    2700                 }
    2701                 else if (eHostMode == PortMode_TCP)
    2702                 {
    2703                     InsertConfigString(pLunL0,  "Driver", "Char");
    2704                     InsertConfigNode(pLunL0,    "AttachedDriver", &pLunL1);
    2705                     InsertConfigString(pLunL1,  "Driver", "TCP");
    2706                     InsertConfigNode(pLunL1,    "Config", &pLunL2);
    2707                     InsertConfigString(pLunL2,  "Location", bstr);
    2708                     InsertConfigInteger(pLunL2, "IsServer", fServer);
    2709                 }
    2710                 else if (eHostMode == PortMode_RawFile)
    2711                 {
    2712                     InsertConfigString(pLunL0,  "Driver", "Char");
    2713                     InsertConfigNode(pLunL0,    "AttachedDriver", &pLunL1);
    2714                     InsertConfigString(pLunL1,  "Driver", "RawFile");
    2715                     InsertConfigNode(pLunL1,    "Config", &pLunL2);
    2716                     InsertConfigString(pLunL2,  "Location", bstr);
    2717                 }
     2689                rc = i_configSerialPort(pInst, eHostMode, Utf8Str(bstr).c_str(), RT_BOOL(fServer));
     2690                if (RT_FAILURE(rc))
     2691                    return rc;
    27182692            }
    27192693        }
     
    58575831}
    58585832
     5833
     5834/**
     5835 * Configures the serial port at the given CFGM node with the supplied parameters.
     5836 *
     5837 * @returns VBox status code.
     5838 * @param   pInst               The instance CFGM node.
     5839 * @param   ePortMode           The port mode to sue.
     5840 * @param   pszPath             The
     5841 */
     5842int Console::i_configSerialPort(PCFGMNODE pInst, PortMode_T ePortMode, const char *pszPath, bool fServer)
     5843{
     5844    PCFGMNODE pLunL0 = NULL;        /* /Devices/Dev/0/LUN#0/ */
     5845    PCFGMNODE pLunL1 = NULL;        /* /Devices/Dev/0/LUN#0/AttachedDriver/ */
     5846    PCFGMNODE pLunL1Cfg = NULL;     /* /Devices/Dev/0/LUN#0/AttachedDriver/Config */
     5847
     5848    try
     5849    {
     5850        InsertConfigNode(pInst, "LUN#0", &pLunL0);
     5851        if (ePortMode == PortMode_HostPipe)
     5852        {
     5853            InsertConfigString(pLunL0,     "Driver", "Char");
     5854            InsertConfigNode(pLunL0,       "AttachedDriver", &pLunL1);
     5855            InsertConfigString(pLunL1,     "Driver", "NamedPipe");
     5856            InsertConfigNode(pLunL1,       "Config", &pLunL1Cfg);
     5857            InsertConfigString(pLunL1Cfg,  "Location", pszPath);
     5858            InsertConfigInteger(pLunL1Cfg, "IsServer", fServer);
     5859        }
     5860        else if (ePortMode == PortMode_HostDevice)
     5861        {
     5862            InsertConfigString(pLunL0,     "Driver", "Host Serial");
     5863            InsertConfigNode(pLunL0,       "Config", &pLunL1);
     5864            InsertConfigString(pLunL1,     "DevicePath", pszPath);
     5865        }
     5866        else if (ePortMode == PortMode_TCP)
     5867        {
     5868            InsertConfigString(pLunL0,     "Driver", "Char");
     5869            InsertConfigNode(pLunL0,       "AttachedDriver", &pLunL1);
     5870            InsertConfigString(pLunL1,     "Driver", "TCP");
     5871            InsertConfigNode(pLunL1,       "Config", &pLunL1Cfg);
     5872            InsertConfigString(pLunL1Cfg,  "Location", pszPath);
     5873            InsertConfigInteger(pLunL1Cfg, "IsServer", fServer);
     5874        }
     5875        else if (ePortMode == PortMode_RawFile)
     5876        {
     5877            InsertConfigString(pLunL0,     "Driver", "Char");
     5878            InsertConfigNode(pLunL0,       "AttachedDriver", &pLunL1);
     5879            InsertConfigString(pLunL1,     "Driver", "RawFile");
     5880            InsertConfigNode(pLunL1,       "Config", &pLunL1Cfg);
     5881            InsertConfigString(pLunL1Cfg,  "Location", pszPath);
     5882        }
     5883    }
     5884    catch (ConfigError &x)
     5885    {
     5886        /* InsertConfig threw something */
     5887        return x.m_vrc;
     5888    }
     5889
     5890    return VINF_SUCCESS;
     5891}
     5892
     5893
    58595894#ifdef VBOX_WITH_GUEST_PROPS
    58605895
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