VirtualBox

Changeset 70766 in vbox


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
Files:
6 edited

Legend:

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

    r68487 r70766  
    21112111            CHECK_ERROR_BREAK(console, ClearAllDiskEncryptionPasswords());
    21122112        }
     2113        else if (!strncmp(a->argv[1], "changeuartmode", 14))
     2114        {
     2115            unsigned n = parseNum(&a->argv[1][14], 4, "UART");
     2116            if (!n)
     2117            {
     2118                rc = E_FAIL;
     2119                break;
     2120            }
     2121            if (a->argc < 3)
     2122            {
     2123                errorArgument("Missing argument to '%s'", a->argv[1]);
     2124                rc = E_FAIL;
     2125                break;
     2126            }
     2127
     2128            ComPtr<ISerialPort> uart;
     2129
     2130            CHECK_ERROR_BREAK(sessionMachine, GetSerialPort(n - 1, uart.asOutParam()));
     2131            ASSERT(uart);
     2132
     2133            if (!RTStrICmp(a->argv[2], "disconnected"))
     2134            {
     2135                if (a->argc != 3)
     2136                {
     2137                    errorArgument("Incorrect arguments to '%s'", a->argv[1]);
     2138                    rc = E_FAIL;
     2139                    break;
     2140                }
     2141                CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_Disconnected));
     2142            }
     2143            else if (   !RTStrICmp(a->argv[2], "server")
     2144                     || !RTStrICmp(a->argv[2], "client")
     2145                     || !RTStrICmp(a->argv[2], "tcpserver")
     2146                     || !RTStrICmp(a->argv[2], "tcpclient")
     2147                     || !RTStrICmp(a->argv[2], "file"))
     2148            {
     2149                const char *pszMode = a->argv[2];
     2150                if (a->argc != 4)
     2151                {
     2152                    errorArgument("Incorrect arguments to '%s'", a->argv[1]);
     2153                    rc = E_FAIL;
     2154                    break;
     2155                }
     2156
     2157                CHECK_ERROR(uart, COMSETTER(Path)(Bstr(a->argv[3]).raw()));
     2158
     2159                /*
     2160                 * Change to disconnected first to get changes in just a parameter causing
     2161                 * the correct changes later on.
     2162                 */
     2163                CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_Disconnected));
     2164                if (!RTStrICmp(pszMode, "server"))
     2165                {
     2166                    CHECK_ERROR(uart, COMSETTER(Server)(TRUE));
     2167                    CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_HostPipe));
     2168                }
     2169                else if (!RTStrICmp(pszMode, "client"))
     2170                {
     2171                    CHECK_ERROR(uart, COMSETTER(Server)(FALSE));
     2172                    CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_HostPipe));
     2173                }
     2174                else if (!RTStrICmp(pszMode, "tcpserver"))
     2175                {
     2176                    CHECK_ERROR(uart, COMSETTER(Server)(TRUE));
     2177                    CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_TCP));
     2178                }
     2179                else if (!RTStrICmp(pszMode, "tcpclient"))
     2180                {
     2181                    CHECK_ERROR(uart, COMSETTER(Server)(FALSE));
     2182                    CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_TCP));
     2183                }
     2184                else if (!RTStrICmp(pszMode, "file"))
     2185                {
     2186                    CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_RawFile));
     2187                }
     2188            }
     2189            else
     2190            {
     2191                if (a->argc != 3)
     2192                {
     2193                    errorArgument("Incorrect arguments to '%s'", a->argv[1]);
     2194                    rc = E_FAIL;
     2195                    break;
     2196                }
     2197                CHECK_ERROR(uart, COMSETTER(Path)(Bstr(a->argv[2]).raw()));
     2198                CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_HostDevice));
     2199            }
     2200        }
    21132201        else
    21142202        {
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp

    r70712 r70766  
    850850                     "                            removeencpassword <id>\n"
    851851                     "                            removeallencpasswords\n"
     852                     "                            changeuartmode<1-N> disconnected|\n"
     853                     "                                                server <pipe>|\n"
     854                     "                                                client <pipe>|\n"
     855                     "                                                tcpserver <port>|\n"
     856                     "                                                tcpclient <hostname:port>|\n"
     857                     "                                                file <file>|\n"
     858                     "                                                <devicename>]\n"
    852859                     "\n", SEP);
    853860    }
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r70534 r70766  
    713713                        PCFGMNODE pLunL0, PCFGMNODE pInst,
    714714                        bool fAttachDetach, bool fIgnoreConnectFailure);
    715 
     715    int i_configSerialPort(PCFGMNODE pInst, PortMode_T ePortMode, const char *pszPath, bool fServer);
    716716    static DECLCALLBACK(int) i_configGuestProperties(void *pvConsole, PUVM pUVM);
    717717    static DECLCALLBACK(int) i_configGuestControl(void *pvConsole);
     
    728728                                                       unsigned uInstance, unsigned uLun,
    729729                                                       INetworkAdapter *aNetworkAdapter);
     730    static DECLCALLBACK(int) i_changeSerialPortAttachment(Console *pThis, PUVM pUVM,
     731                                                          ISerialPort *pSerialPort);
    730732
    731733    void i_changeClipboardMode(ClipboardMode_T aClipboardMode);
     
    974976    unsigned               m_cDisksPwProvided;
    975977
     978    /** Current active port modes of the supported serial ports. */
     979    PortMode_T             m_aeSerialPortMode[4];
     980
    976981    /** Pointer to the key consumer -> provider (that's us) callbacks. */
    977982    struct MYPDMISECKEY : public PDMISECKEY
  • 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
  • trunk/src/VBox/Main/src-server/SerialPortImpl.cpp

    r69500 r70766  
    250250{
    251251    /* the machine needs to be mutable */
    252     AutoMutableOrSavedStateDependency adep(m->pMachine);
     252    AutoMutableOrSavedOrRunningStateDependency adep(m->pMachine);
    253253    if (FAILED(adep.rc())) return adep.rc();
    254254
     
    424424{
    425425    /* the machine needs to be mutable */
    426     AutoMutableOrSavedStateDependency adep(m->pMachine);
     426    AutoMutableOrSavedOrRunningStateDependency adep(m->pMachine);
    427427    if (FAILED(adep.rc())) return adep.rc();
    428428
     
    463463{
    464464    /* the machine needs to be mutable */
    465     AutoMutableOrSavedStateDependency adep(m->pMachine);
     465    AutoMutableOrSavedOrRunningStateDependency adep(m->pMachine);
    466466    if (FAILED(adep.rc())) return adep.rc();
    467467
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