VirtualBox

Changeset 35454 in vbox for trunk/src/VBox/Main/webservice


Ignore:
Timestamp:
Jan 10, 2011 12:06:19 PM (14 years ago)
Author:
vboxsync
Message:

Main/webservice: use VirtualBoxClient to detect VBoxSVC crashes and recover correctly by deleting the sessions, plus some minor cleanups

Location:
trunk/src/VBox/Main/webservice
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/webservice/vboxweb.cpp

    r35154 r35454  
    66 *      server, to which clients can connect.
    77 *
    8  * Copyright (C) 2006-2010 Oracle Corporation
     8 * Copyright (C) 2006-2011 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2222// vbox headers
    2323#include <VBox/com/com.h>
     24#include <VBox/com/array.h>
    2425#include <VBox/com/ErrorInfo.h>
    2526#include <VBox/com/errorprint.h>
    2627#include <VBox/com/EventQueue.h>
     28#include <VBox/com/listeners.h>
    2729#include <VBox/VBoxAuth.h>
    2830#include <VBox/version.h>
     
    8688 ****************************************************************************/
    8789
     90ComPtr<IVirtualBoxClient> g_pVirtualBoxClient = NULL;
    8891ComPtr<IVirtualBox>     g_pVirtualBox = NULL;
    8992
     
    98101int                     g_iWatchdogCheckInterval = 5;
    99102
    100 const char              *g_pcszBindToHost = NULL;       // host; NULL = current machine
     103const char              *g_pcszBindToHost = NULL;       // host; NULL = localhost
    101104unsigned int            g_uBindToPort = 18083;          // port
    102105unsigned int            g_uBacklog = 100;               // backlog = max queue size for requests
     
    125128// this mutex protects the auth lib and authentication
    126129util::WriteLockHandle  *g_pAuthLibLockHandle;
     130
     131// this mutex protects the global VirtualBox reference
     132util::RWLockHandle  *g_pVirtualBoxLockHandle;
    127133
    128134// this mutex protects all of the below
     
    472478}
    473479
     480/****************************************************************************
     481 *
     482 * VirtualBoxClient event listener
     483 *
     484 ****************************************************************************/
     485
     486class VirtualBoxClientEventListener
     487{
     488public:
     489    VirtualBoxClientEventListener()
     490    {
     491    }
     492
     493    virtual ~VirtualBoxClientEventListener()
     494    {
     495    }
     496
     497    STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *aEvent)
     498    {
     499        switch (aType)
     500        {
     501            case VBoxEventType_OnVBoxSVCAvailabilityChanged:
     502            {
     503                ComPtr<IVBoxSVCAvailabilityChangedEvent> pVSACEv = aEvent;
     504                Assert(pVSACEv);
     505                BOOL fAvailable = FALSE;
     506                pVSACEv->COMGETTER(Available)(&fAvailable);
     507                if (!fAvailable)
     508                {
     509                    WebLog("VBoxSVC became unavailable\n");
     510                    {
     511                        util::AutoWriteLock vlock(g_pVirtualBoxLockHandle COMMA_LOCKVAL_SRC_POS);
     512                        g_pVirtualBox = NULL;
     513                    }
     514                    {
     515                        // we're messing with sessions, so lock them
     516                        util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS);
     517                        WEBDEBUG(("SVC unavailable: deleting %d sessions\n", g_mapSessions.size()));
     518
     519                        SessionsMap::iterator it = g_mapSessions.begin(),
     520                                              itEnd = g_mapSessions.end();
     521                        while (it != itEnd)
     522                        {
     523                            WebServiceSession *pSession = it->second;
     524                            WEBDEBUG(("SVC unavailable: Session %llX stale, deleting\n", pSession->getID()));
     525                            delete pSession;
     526                            it = g_mapSessions.begin();
     527                        }
     528                    }
     529                }
     530                else
     531                {
     532                    WebLog("VBoxSVC became available\n");
     533                    util::AutoWriteLock vlock(g_pVirtualBoxLockHandle COMMA_LOCKVAL_SRC_POS);
     534                    HRESULT hrc = g_pVirtualBoxClient->COMGETTER(VirtualBox)(g_pVirtualBox.asOutParam());
     535                    AssertComRC(hrc);
     536                }
     537                break;
     538            }
     539            default:
     540                AssertFailed();
     541        }
     542
     543        return S_OK;
     544    }
     545
     546private:
     547};
     548
     549typedef ListenerImpl<VirtualBoxClientEventListener> VirtualBoxClientEventListenerImpl;
     550
     551VBOX_LISTENER_DECLARE(VirtualBoxClientEventListenerImpl)
     552
    474553/**
    475554 * Implementation for WEBLOG macro defined in vboxweb.h; this prints a message
     
    561640    int m, s; // master and slave sockets
    562641    m = soap_bind(&soap,
    563                   g_pcszBindToHost,     // host: current machine
    564                   g_uBindToPort,     // port
    565                   g_uBacklog);     // backlog = max queue size for requests
     642                  g_pcszBindToHost ? g_pcszBindToHost : "localhost",    // safe default host
     643                  g_uBindToPort,    // port
     644                  g_uBacklog);      // backlog = max queue size for requests
    566645    if (m < 0)
    567646        WebLogSoapError(&soap);
     
    624703 * @return
    625704 */
    626 int main(int argc, char* argv[])
     705int main(int argc, char *argv[])
    627706{
    628707    // initialize runtime
     
    648727        {
    649728            case 'H':
    650                 g_pcszBindToHost = ValueUnion.psz;
     729                if (!ValueUnion.psz || !*ValueUnion.psz)
     730                {
     731                    /* Normalize NULL/empty string to NULL, which will be
     732                     * interpreted as "localhost" below. */
     733                    g_pcszBindToHost = NULL;
     734                }
     735                else
     736                    g_pcszBindToHost = ValueUnion.psz;
    651737                break;
    652738
     
    723809        return RTMsgErrorExit(RTEXITCODE_FAILURE, "failed to initialize COM! hrc=%Rhrc\n", hrc);
    724810
    725     ComPtr<ISession> session;
    726 
    727     hrc = g_pVirtualBox.createLocalObject(CLSID_VirtualBox);
     811    hrc = g_pVirtualBoxClient.createInprocObject(CLSID_VirtualBoxClient);
    728812    if (FAILED(hrc))
    729         RTMsgError("failed to create the VirtualBox object!");
    730     else
    731     {
    732         hrc = session.createInprocObject(CLSID_Session);
    733         if (FAILED(hrc))
    734             RTMsgError("failed to create a session object!");
    735     }
    736 
    737     if (FAILED(hrc))
    738     {
     813    {
     814        RTMsgError("failed to create the VirtualBoxClient object!");
    739815        com::ErrorInfo info;
    740816        if (!info.isFullAvailable() && !info.isBasicAvailable())
     
    748824    }
    749825
     826    hrc = g_pVirtualBoxClient->COMGETTER(VirtualBox)(g_pVirtualBox.asOutParam());
     827    if (FAILED(hrc))
     828    {
     829        RTMsgError("Failed to get VirtualBox object (rc=%Rhrc)!", hrc);
     830        return RTEXITCODE_FAILURE;
     831    }
     832
     833    /* VirtualBoxClient events registration. */
     834    IEventListener *vboxClientListener = NULL;
     835    {
     836        ComPtr<IEventSource> pES;
     837        CHECK_ERROR(g_pVirtualBoxClient, COMGETTER(EventSource)(pES.asOutParam()));
     838        vboxClientListener = new VirtualBoxClientEventListenerImpl();
     839        com::SafeArray<VBoxEventType_T> eventTypes;
     840        eventTypes.push_back(VBoxEventType_OnVBoxSVCAvailabilityChanged);
     841        CHECK_ERROR(pES, RegisterListener(vboxClientListener, ComSafeArrayAsInParam(eventTypes), true));
     842    }
     843
    750844    // create the global mutexes
    751845    g_pAuthLibLockHandle = new util::WriteLockHandle(util::LOCKCLASS_WEBSERVICE);
     846    g_pVirtualBoxLockHandle = new util::RWLockHandle(util::LOCKCLASS_WEBSERVICE);
    752847    g_pSessionsLockHandle = new util::WriteLockHandle(util::LOCKCLASS_WEBSERVICE);
    753848    g_pThreadsLockHandle = new util::RWLockHandle(util::LOCKCLASS_OBJECTSTATE);
     
    788883        if (RT_FAILURE(rc))
    789884            RTMsgError("processEventQueue -> %Rrc", rc);
     885    }
     886
     887    /* VirtualBoxClient events unregistration. */
     888    if (vboxClientListener)
     889    {
     890        ComPtr<IEventSource> pES;
     891        CHECK_ERROR(g_pVirtualBoxClient, COMGETTER(EventSource)(pES.asOutParam()));
     892        if (!pES.isNull())
     893            CHECK_ERROR(pES, UnregisterListener(vboxClientListener));
     894        vboxClientListener->Release();
    790895    }
    791896
     
    11241229
    11251230int WebServiceSession::authenticate(const char *pcszUsername,
    1126                                     const char *pcszPassword)
     1231                                    const char *pcszPassword,
     1232                                    IVirtualBox **ppVirtualBox)
    11271233{
    11281234    int rc = VERR_WEB_NOT_AUTHENTICATED;
     1235    ComPtr<IVirtualBox> pVirtualBox;
     1236    {
     1237        util::AutoReadLock vlock(g_pVirtualBoxLockHandle COMMA_LOCKVAL_SRC_POS);
     1238        pVirtualBox = g_pVirtualBox;
     1239    }
     1240    pVirtualBox.queryInterfaceTo(ppVirtualBox);
     1241    if (pVirtualBox.isNull())
     1242        return rc;
    11291243
    11301244    util::AutoReadLock lock(g_pAuthLibLockHandle COMMA_LOCKVAL_SRC_POS);
     
    11391253        // retrieve authentication library from system properties
    11401254        ComPtr<ISystemProperties> systemProperties;
    1141         g_pVirtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam());
     1255        pVirtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam());
    11421256
    11431257        com::Bstr authLibrary;
     
    12191333            // (and of which IWebsessionManager::getSessionObject returns a managed object reference)
    12201334            ComPtr<ISession> session;
    1221             if (FAILED(rc = session.createInprocObject(CLSID_Session)))
     1335            rc = g_pVirtualBoxClient->COMGETTER(Session)(session.asOutParam());
     1336            if (FAILED(rc))
    12221337            {
    12231338                WEBDEBUG(("ERROR: cannot create session object!"));
     
    15381653    _vbox__IManagedObjectRef_USCOREgetInterfaceNameResponse *resp)
    15391654{
    1540     HRESULT rc = SOAP_OK;
     1655    HRESULT rc = S_OK;
    15411656    WEBDEBUG(("-- entering %s\n", __FUNCTION__));
    15421657
     
    15731688    _vbox__IManagedObjectRef_USCOREreleaseResponse *resp)
    15741689{
    1575     HRESULT rc = SOAP_OK;
     1690    HRESULT rc = S_OK;
    15761691    WEBDEBUG(("-- entering %s\n", __FUNCTION__));
    15771692
     
    16401755 */
    16411756int __vbox__IWebsessionManager_USCORElogon(
    1642         struct soap*,
     1757        struct soap *soap,
    16431758        _vbox__IWebsessionManager_USCORElogon *req,
    16441759        _vbox__IWebsessionManager_USCORElogonResponse *resp)
    16451760{
    1646     HRESULT rc = SOAP_OK;
     1761    HRESULT rc = S_OK;
    16471762    WEBDEBUG(("-- entering %s\n", __FUNCTION__));
    16481763
     
    16551770        // in the global map automatically
    16561771        WebServiceSession *pSession = new WebServiceSession();
     1772        ComPtr<IVirtualBox> pVirtualBox;
    16571773
    16581774        // authenticate the user
    16591775        if (!(pSession->authenticate(req->username.c_str(),
    1660                                      req->password.c_str())))
     1776                                     req->password.c_str(),
     1777                                     pVirtualBox.asOutParam())))
    16611778        {
    16621779            // in the new session, create a managed object reference (MOR) for the
     
    16641781            // that it will be implicitly be included in all future requests of this
    16651782            // webservice client
    1666             ComPtr<IUnknown> p2 = g_pVirtualBox;
     1783            ComPtr<IUnknown> p2 = pVirtualBox;
     1784            if (pVirtualBox.isNull() || p2.isNull())
     1785            {
     1786                rc = E_FAIL;
     1787                break;
     1788            }
    16671789            ManagedObjectRef *pRef = new ManagedObjectRef(*pSession,
    16681790                                                          p2,                       // IUnknown *pobjUnknown
    1669                                                           g_pVirtualBox,            // void *pobjInterface
     1791                                                          pVirtualBox,              // void *pobjInterface
    16701792                                                          COM_IIDOF(IVirtualBox),
    16711793                                                          g_pcszIVirtualBox);
     
    16731795            WEBDEBUG(("VirtualBox object ref is %s\n", resp->returnval.c_str()));
    16741796        }
     1797        else
     1798            rc = E_FAIL;
    16751799    } while (0);
    16761800
     
    16901814        _vbox__IWebsessionManager_USCOREgetSessionObjectResponse *resp)
    16911815{
    1692     HRESULT rc = SOAP_OK;
     1816    HRESULT rc = S_OK;
    16931817    WEBDEBUG(("-- entering %s\n", __FUNCTION__));
    16941818
     
    17231847        _vbox__IWebsessionManager_USCORElogoffResponse *resp)
    17241848{
    1725     HRESULT rc = SOAP_OK;
     1849    HRESULT rc = S_OK;
    17261850    WEBDEBUG(("-- entering %s\n", __FUNCTION__));
    17271851
  • trunk/src/VBox/Main/webservice/vboxweb.h

    r32780 r35454  
    33 *      header file for "real" web server code.
    44 *
    5  * Copyright (C) 2006-2010 Oracle Corporation
     5 * Copyright (C) 2006-2011 Oracle Corporation
    66 *
    77 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    134134
    135135        int authenticate(const char *pcszUsername,
    136                          const char *pcszPassword);
     136                         const char *pcszPassword,
     137                         IVirtualBox **ppVirtualBox);
    137138
    138139        ManagedObjectRef* findRefFromPtr(const IUnknown *pObject);
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