VirtualBox

Changeset 103300 in vbox for trunk/src/libs


Ignore:
Timestamp:
Feb 11, 2024 8:33:57 PM (13 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
161594
Message:

libs/xpcom,Main: Disabled code to move VBoxXPCOMIPCD into VBoxSVC, bugref:10594

Location:
trunk/src/libs/xpcom18a4
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/libs/xpcom18a4/Makefile.kmk

    r102470 r103300  
    106106        VBoxXPCOM \
    107107        VBoxXPCOMIPCC
     108 ifdef VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC
     109  VBOX_XPCOM_DLLS += \
     110        VBoxXPCOMIPCD
     111 endif
     112
    108113 DLLS += $(VBOX_XPCOM_DLLS)
    109114
     
    134139        tstPrimitiveTest
    135140 endif # VBOX_WITH_TESTCASES
    136  PROGRAMS += VBoxXPCOMIPCD
     141 ifndef VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC
     142  PROGRAMS += VBoxXPCOMIPCD
     143 endif
    137144
    138145endif # !VBOX_ONLY_SDK && (!defined(VBOX_ONLY_EXTPACKS) || !defined(VBOX_ONLY_EXTPACKS_USE_IMPLIBS))
     
    754761TEMPLATE_XPComIpcDll                  = XPCOM IPC libraries
    755762TEMPLATE_XPComIpcDll_EXTENDS          = XPComDll
    756 TEMPLATE_XPComIpcDll_DEFS             = $(TEMPLATE_XPComDll_DEFS) BUILD_DCONNECT=1
    757 ifdef VBOX_WITH_AUTOMATIC_DEFS_QUOTING
    758  TEMPLATE_XPComIpcDll_DEFS           += IPC_DAEMON_APP_NAME="VBoxXPCOMIPCD$(SUFF_EXE)"
     763TEMPLATE_XPComIpcDll_DEFS             = \
     764        $(TEMPLATE_XPComDll_DEFS) \
     765        BUILD_DCONNECT=1 \
     766        $(if $(VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC),VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC,)
     767
     768ifdef VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC
     769 ifdef VBOX_WITH_AUTOMATIC_DEFS_QUOTING
     770  TEMPLATE_XPComIpcDll_DEFS           += IPC_DAEMON_APP_NAME="VBoxSVC$(SUFF_EXE)"
     771 else
     772  TEMPLATE_XPComIpcDll_DEFS           += IPC_DAEMON_APP_NAME=\"VBoxSVC$(SUFF_EXE)\"
     773 endif
    759774else
    760  TEMPLATE_XPComIpcDll_DEFS           += IPC_DAEMON_APP_NAME=\"VBoxXPCOMIPCD$(SUFF_EXE)\"
     775 ifdef VBOX_WITH_AUTOMATIC_DEFS_QUOTING
     776  TEMPLATE_XPComIpcDll_DEFS           += IPC_DAEMON_APP_NAME="VBoxXPCOMIPCD$(SUFF_EXE)"
     777 else
     778  TEMPLATE_XPComIpcDll_DEFS           += IPC_DAEMON_APP_NAME=\"VBoxXPCOMIPCD$(SUFF_EXE)\"
     779 endif
    761780endif
    762781ifdef IPC_LOGGING
     
    808827VBoxXPCOMIPCC_TEMPLATE = XPComIpcDll
    809828VBoxXPCOMIPCC_INST = $(INST_BIN)components/
    810 #VBoxXPCOMIPCC_DEFS = HAVE_DEPENDENT_LIBS - dependentLibs.h is linux specific, so this cannot be required.
    811829VBoxXPCOMIPCC_SOURCES = \
    812830        ipc/ipcd/client/src/ipcdclient.cpp \
     
    839857# DCONNECT daemon executable
    840858#
    841 VBoxXPCOMIPCD_TEMPLATE = XPComIpcExe
    842 VBoxXPCOMIPCD_SOURCES = \
    843         ipc/ipcd/daemon/src/ipcd.cpp \
    844         ipc/ipcd/daemon/src/ipcClient.cpp \
    845         ipc/ipcd/daemon/src/ipcCommandModule.cpp \
    846         ipc/ipcd/daemon/src/ipcdUnix.cpp
     859ifdef VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC
     860 VBoxXPCOMIPCD_TEMPLATE = XPComIpcDll
     861 VBoxXPCOMIPCD_SOURCES = \
     862        ipc/ipcd/daemon/src/ipcd.cpp \
     863        ipc/ipcd/daemon/src/ipcClient.cpp \
     864        ipc/ipcd/daemon/src/ipcCommandModule.cpp \
     865        ipc/ipcd/daemon/src/ipcdUnix.cpp
     866 VBoxXPCOMIPCD_LIBS = \
     867        $(VBox-xpcom-ipcshared_1_TARGET) \
     868        $(VBoxXPCOM_1_TARGET) \
     869        $(TEMPLATE_XPComDll_LIBS)
     870else
     871 VBoxXPCOMIPCD_TEMPLATE = XPComIpcExe
     872 VBoxXPCOMIPCD_SOURCES = \
     873        ipc/ipcd/daemon/src/ipcd.cpp \
     874        ipc/ipcd/daemon/src/ipcClient.cpp \
     875        ipc/ipcd/daemon/src/ipcCommandModule.cpp \
     876        ipc/ipcd/daemon/src/ipcdUnix.cpp
     877endif
    847878
    848879
  • trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp

    r102470 r103300  
    12421242    {
    12431243      char szPipeInheritFd[32]; RT_ZERO(szPipeInheritFd);
    1244       const char *const s_apszArgs[] = { (char *const) path, "--inherit-startup-pipe", &szPipeInheritFd[0], NULL };
     1244      const char *const s_apszArgs[] = { (char *const) path,
     1245#ifdef VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC
     1246                                         "--auto-shutdown",
     1247#endif
     1248                                         "--inherit-startup-pipe",
     1249                                         &szPipeInheritFd[0], NULL };
    12451250      char c;
    12461251
  • trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcdPrivate.h

    r103055 r103300  
    4848// XXX may want to make this more dynamic
    4949//
    50 #define IPC_MAX_CLIENTS 10000
     50#ifdef VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC
     51# define IPC_MAX_CLIENTS 100
     52#else
     53# define IPC_MAX_CLIENTS 10000
     54#endif
    5155
    5256/** List of connected IPC clients. */
  • trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcdUnix.cpp

    r103116 r103300  
    3737#define LOG_GROUP LOG_GROUP_IPC
    3838#include <iprt/assert.h>
    39 #include <iprt/errcore.h>
     39#include <iprt/err.h>
    4040#include <iprt/initterm.h>
    4141#include <iprt/getopt.h>
     
    4444#include <iprt/socket.h>
    4545#include <iprt/string.h>
     46#ifdef VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC
     47# include <iprt/thread.h>
     48#endif
    4649#include <VBox/log.h>
    4750
     
    6568#include "ipcd.h"
    6669
     70
     71/**
     72 * The IPC daemon state
     73 */
     74typedef struct IPCDSTATE
     75{
     76    RTSOCKET hSockListen;
     77    int      fdListen;
     78    int      ipcLockFD;
     79    int      ipcClientCount;
     80
     81    //
     82    // the first element of this array is always zero; this is done so that the
     83    // k'th element of ipcClientArray corresponds to the k'th element of
     84    // ipcPollList.
     85    //
     86    ipcClient ipcClientArray[IPC_MAX_CLIENTS];
     87
     88    RTPOLLSET hPollSet;
     89
     90#ifdef VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC
     91    RTTHREAD hThread;
     92#endif
     93} IPCDSTATE;
     94typedef IPCDSTATE *PIPCDSTATE;
     95typedef const IPCDSTATE *PCIPCDSTATE;
     96
     97
    6798//-----------------------------------------------------------------------------
    6899// ipc directory and locking...
    69100//-----------------------------------------------------------------------------
    70 
    71 //
    72 // advisory file locking is used to ensure that only one IPC daemon is active
    73 // and bound to the local domain socket at a time.
    74 //
    75 // XXX this code does not work on OS/2.
    76 //
    77 #if !defined(XP_OS2)
    78 #define IPC_USE_FILE_LOCK
    79 #endif
    80 
    81 #ifdef IPC_USE_FILE_LOCK
    82101
    83102enum Status
     
    89108};
    90109
    91 static int ipcLockFD = 0;
    92 
    93 static Status AcquireDaemonLock(const char *baseDir)
     110static Status AcquireDaemonLock(PIPCDSTATE pThis, const char *baseDir)
    94111{
    95112    const char lockName[] = "lock";
     
    100117            + sizeof(lockName); // "lock"
    101118
    102 #ifdef VBOX
    103119    //
    104120    // Security checks for the directory
     
    107123    if (stat(baseDir, &st) == -1)
    108124    {
    109         printf("Cannot stat '%s'.\n", baseDir);
     125        LogFlowFunc(("Cannot stat '%s'.\n", baseDir));
    110126        return ELockFileOwner;
    111127    }
     
    113129    if (st.st_uid != getuid() && st.st_uid != geteuid())
    114130    {
    115         printf("Wrong owner (%d) of '%s'", st.st_uid, baseDir);
     131        LogFlowFunc(("Wrong owner (%d) of '%s'", st.st_uid, baseDir));
    116132        if (   !stat("/tmp", &st)
    117133            && (st.st_mode & 07777) != 01777)
    118             printf(" -- check /tmp permissions (%o should be 1777)\n",
    119                     st.st_mode & 07777);
    120         printf(".\n");
     134            LogFlowFunc((" -- check /tmp permissions (%o should be 1777)\n",
     135                         st.st_mode & 07777));
     136        LogFlowFunc((".\n"));
    121137        return ELockFileOwner;
    122138    }
     
    124140    if (st.st_mode != (S_IRUSR | S_IWUSR | S_IXUSR | S_IFDIR))
    125141    {
    126         printf("Wrong mode (%o) of '%s'", st.st_mode, baseDir);
     142        LogFlowFunc(("Wrong mode (%o) of '%s'", st.st_mode, baseDir));
    127143        if (   !stat("/tmp", &st)
    128144            && (st.st_mode & 07777) != 01777)
    129             printf(" -- check /tmp permissions (%o should be 1777)\n",
    130                     st.st_mode & 07777);
    131         printf(".\n");
     145            LogFlowFunc((" -- check /tmp permissions (%o should be 1777)\n",
     146                    st.st_mode & 07777));
     147        LogFlowFunc((".\n"));
    132148        return ELockFileOwner;
    133149    }
    134 #endif
    135150
    136151    char *lockFile = (char *) malloc(len);
     
    142157    // open lock file.  it remains open until we shutdown.
    143158    //
    144     ipcLockFD = open(lockFile, O_WRONLY|O_CREAT, S_IWUSR|S_IRUSR);
    145 
    146 #ifndef VBOX
    147     free(lockFile);
    148 #endif
    149 
    150     if (ipcLockFD == -1)
     159    pThis->ipcLockFD = open(lockFile, O_WRONLY|O_CREAT, S_IWUSR|S_IRUSR);
     160    if (pThis->ipcLockFD == -1)
    151161    {
    152162        free(lockFile);
     
    154164    }
    155165
    156 #ifdef VBOX
    157166    //
    158167    // Security checks for the lock file
    159168    //
    160     if (fstat(ipcLockFD, &st) == -1)
    161     {
    162         printf("Cannot stat '%s'.\n", lockFile);
     169    if (fstat(pThis->ipcLockFD, &st) == -1)
     170    {
     171        LogFlowFunc(("Cannot stat '%s'.\n", lockFile));
    163172        free(lockFile);
    164173        return ELockFileOwner;
     
    167176    if (st.st_uid != getuid() && st.st_uid != geteuid())
    168177    {
    169         printf("Wrong owner (%d) of '%s'.\n", st.st_uid, lockFile);
     178        LogFlowFunc(("Wrong owner (%d) of '%s'.\n", st.st_uid, lockFile));
    170179        free(lockFile);
    171180        return ELockFileOwner;
     
    174183    if (st.st_mode != (S_IRUSR | S_IWUSR | S_IFREG))
    175184    {
    176         printf("Wrong mode (%o) of '%s'.\n", st.st_mode, lockFile);
     185        LogFlowFunc(("Wrong mode (%o) of '%s'.\n", st.st_mode, lockFile));
    177186        free(lockFile);
    178187        return ELockFileOwner;
     
    180189
    181190    free(lockFile);
    182 #endif
    183191
    184192    //
     
    193201    lock.l_len = 0;
    194202    lock.l_whence = SEEK_SET;
    195     if (fcntl(ipcLockFD, F_SETLK, &lock) == -1)
     203    if (fcntl(pThis->ipcLockFD, F_SETLK, &lock) == -1)
     204    {
     205        LogFlowFunc(("Setting lock failed -> %Rrc.\n", RTErrConvertFromErrno(errno)));
    196206        return ELockFileLock;
     207    }
    197208
    198209    //
    199210    // truncate lock file once we have exclusive access to it.
    200211    //
    201     ftruncate(ipcLockFD, 0);
     212    ftruncate(pThis->ipcLockFD, 0);
    202213
    203214    //
     
    209220    if (nb <= 0)
    210221        return ELockFileOpen;
    211     write(ipcLockFD, buf, (size_t)nb);
     222    write(pThis->ipcLockFD, buf, (size_t)nb);
    212223
    213224    return EOk;
    214225}
    215226
    216 static Status InitDaemonDir(const char *socketPath)
     227static Status InitDaemonDir(PIPCDSTATE pThis, const char *socketPath)
    217228{
    218229    LogFlowFunc(("InitDaemonDir [sock=%s]\n", socketPath));
     
    232243    // must be active, so bail.
    233244    //
    234     Status status = AcquireDaemonLock(baseDir);
     245    Status status = AcquireDaemonLock(pThis, baseDir);
    235246
    236247    RTStrFree(baseDir);
     
    243254}
    244255
    245 static void ShutdownDaemonDir()
    246 {
    247     LogFlowFunc(("ShutdownDaemonDir\n"));
    248 
    249     // deleting directory and files underneath it allows another process
    250     // to think it has exclusive access.  better to just leave the hidden
    251     // directory in /tmp and let the OS clean it up via the usual tmpdir
    252     // cleanup cron job.
    253 
    254     // this removes the advisory lock, allowing other processes to acquire it.
    255     if (ipcLockFD) {
    256         close(ipcLockFD);
    257         ipcLockFD = 0;
    258     }
    259 }
    260 
    261 #endif // IPC_USE_FILE_LOCK
    262256
    263257//-----------------------------------------------------------------------------
     
    269263//
    270264DECL_HIDDEN_DATA(RTLISTANCHOR) g_LstIpcClients;
    271 static int                     ipcClientCount = 0;
    272 
    273 //
    274 // the first element of this array is always zero; this is done so that the
    275 // k'th element of ipcClientArray corresponds to the k'th element of
    276 // ipcPollList.
    277 //
    278 static ipcClient ipcClientArray[IPC_MAX_CLIENTS];
    279 
    280265static RTPOLLSET g_hPollSet = NIL_RTPOLLSET;
    281266
    282 //-----------------------------------------------------------------------------
    283 
    284 static int AddClient(RTPOLLSET hPollSet, RTSOCKET hSock)
    285 {
    286     if (ipcClientCount == IPC_MAX_CLIENTS) {
     267
     268//-----------------------------------------------------------------------------
     269
     270static int AddClient(PIPCDSTATE pThis, RTSOCKET hSock)
     271{
     272    if (pThis->ipcClientCount == IPC_MAX_CLIENTS) {
    287273        LogFlowFunc(("reached maximum client limit\n"));
    288274        return -1;
     
    290276
    291277    /* Find an unused client entry. */
    292     for (uint32_t i = 0; i < RT_ELEMENTS(ipcClientArray); i++)
    293     {
    294         if (!ipcClientArray[i].m_fUsed)
     278    for (uint32_t i = 0; i < RT_ELEMENTS(pThis->ipcClientArray); i++)
     279    {
     280        if (!pThis->ipcClientArray[i].m_fUsed)
    295281        {
    296             ipcClientArray[i].Init(i, hSock);
    297             ipcClientArray[i].m_fPollEvts = RTPOLL_EVT_READ;
    298             int vrc = RTPollSetAddSocket(hPollSet, hSock, RTPOLL_EVT_READ, i);
     282            pThis->ipcClientArray[i].Init(i, hSock);
     283            pThis->ipcClientArray[i].m_fPollEvts = RTPOLL_EVT_READ;
     284            int vrc = RTPollSetAddSocket(pThis->hPollSet, hSock, RTPOLL_EVT_READ, i);
    299285            if (RT_SUCCESS(vrc))
    300286            {
    301                 RTListAppend(&g_LstIpcClients, &ipcClientArray[i].NdClients);
    302                 ipcClientCount++;
     287                RTListAppend(&g_LstIpcClients, &pThis->ipcClientArray[i].NdClients);
     288                pThis->ipcClientCount++;
    303289                return 0;
    304290            }
    305291
    306             ipcClientArray[i].Finalize();
     292            pThis->ipcClientArray[i].Finalize();
    307293            break;
    308294        }
     
    313299}
    314300
    315 static int RemoveClient(RTPOLLSET hPollSet, uint32_t idClient)
    316 {
    317     int vrc = RTPollSetRemove(hPollSet, idClient);
     301static int RemoveClient(PIPCDSTATE pThis, uint32_t idClient)
     302{
     303    int vrc = RTPollSetRemove(pThis->hPollSet, idClient);
    318304    AssertRC(vrc); RT_NOREF(vrc);
    319305
    320     RTListNodeRemove(&ipcClientArray[idClient].NdClients);
    321     ipcClientArray[idClient].Finalize();
    322     --ipcClientCount;
     306    RTListNodeRemove(&pThis->ipcClientArray[idClient].NdClients);
     307    pThis->ipcClientArray[idClient].Finalize();
     308    pThis->ipcClientCount--;
    323309    return 0;
    324310}
     
    326312//-----------------------------------------------------------------------------
    327313
    328 static void PollLoop(RTPOLLSET hPollSet, int fdListen)
     314static void PollLoop(PIPCDSTATE pThis)
    329315{
    330316    RTListInit(&g_LstIpcClients);
     
    332318    for (;;)
    333319    {
    334         LogFlowFunc(("Polling [ipcClientCount=%d]\n", ipcClientCount));
     320        LogFlowFunc(("Polling [ipcClientCount=%d]\n", pThis->ipcClientCount));
    335321        uint32_t idPoll = 0;
    336322        uint32_t fEvents = 0;
    337         int vrc = RTPoll(hPollSet, 5 * RT_MS_1MIN, &fEvents, &idPoll);
     323        int vrc = RTPoll(pThis->hPollSet, 5 * RT_MS_1MIN, &fEvents, &idPoll);
    338324        if (RT_SUCCESS(vrc))
    339325        { /* likely */ }
     
    351337            LogFlowFunc(("Got new connection\n"));
    352338
    353             int fdClient = accept(fdListen, NULL, NULL);
     339            int fdClient = accept(pThis->fdListen, NULL, NULL);
    354340            if (fdClient == -1)
    355341            {
     
    363349                if (RT_SUCCESS(vrc))
    364350                {
    365                     if (AddClient(hPollSet, hSock) != 0)
     351                    if (AddClient(pThis, hSock) != 0)
    366352                        RTSocketClose(hSock);
    367353                }
     
    375361        else
    376362        {
    377             uint32_t fNewFlags = ipcClientArray[idPoll].Process(fEvents);
     363            uint32_t fNewFlags = pThis->ipcClientArray[idPoll].Process(fEvents);
    378364            if (!fNewFlags)
    379365            {
    380366                /* Cleanup dead client. */
    381                 RemoveClient(hPollSet, idPoll);
     367                RemoveClient(pThis, idPoll);
    382368
    383369                /* Shutdown if no clients. */
    384                 if (ipcClientCount == 0)
     370                if (pThis->ipcClientCount == 0)
    385371                {
    386372                    LogFlowFunc(("shutting down\n"));
     
    388374                }
    389375            }
    390             else if (ipcClientArray[idPoll].m_fPollEvts != fNewFlags)
     376            else if (pThis->ipcClientArray[idPoll].m_fPollEvts != fNewFlags)
    391377            {
    392378                /* Change flags. */
    393                 vrc = RTPollSetEventsChange(hPollSet, idPoll, fNewFlags);
     379                vrc = RTPollSetEventsChange(pThis->hPollSet, idPoll, fNewFlags);
    394380                AssertRC(vrc);
    395                 ipcClientArray[idPoll].m_fPollEvts = fNewFlags;
     381                pThis->ipcClientArray[idPoll].m_fPollEvts = fNewFlags;
    396382            }
    397383        }
     
    425411}
    426412
    427 //-----------------------------------------------------------------------------
    428 
     413
     414static int ipcdInit(PIPCDSTATE pThis, const char *pszSocketPath)
     415{
     416    pThis->fdListen       = 0;
     417    pThis->hPollSet       = NIL_RTPOLLSET;
     418    pThis->hSockListen    = NIL_RTSOCKET;
     419    pThis->ipcLockFD      = 0;
     420    pThis->ipcClientCount = 0;
     421
     422    struct sockaddr_un addr;
     423    memset(&addr, 0, sizeof(addr));
     424    addr.sun_family = AF_UNIX;
     425
     426    // set socket address
     427    if (!pszSocketPath)
     428        IPC_GetDefaultSocketPath(addr.sun_path, sizeof(addr.sun_path));
     429    else
     430        RTStrCopy(addr.sun_path, sizeof(addr.sun_path), pszSocketPath);
     431
     432    Status status = InitDaemonDir(pThis, addr.sun_path);
     433    if (status != EOk) {
     434        if (status == ELockFileLock)
     435            return VERR_ALREADY_EXISTS;
     436        else
     437        {
     438            LogFlowFunc(("InitDaemonDir failed (status=%d)\n", status));
     439            // don't notify the parent to cause it to fail in PR_Read() after
     440            // we terminate
     441            if (status != ELockFileOwner)
     442                printf(("Cannot create a lock file for '%s'.\n"
     443                        "Check permissions.\n", addr.sun_path));
     444            return VERR_INVALID_PARAMETER;
     445        }
     446    }
     447
     448    pThis->fdListen = socket(PF_UNIX, SOCK_STREAM, 0);
     449    if (pThis->fdListen == -1)
     450    {
     451        LogFlowFunc(("socket failed [%d]\n", errno));
     452        return RTErrConvertFromErrno(errno);
     453    }
     454
     455    if (bind(pThis->fdListen, (struct sockaddr *)&addr, sizeof(addr)))
     456    {
     457        LogFlowFunc(("bind failed [%d]\n", errno));
     458        return RTErrConvertFromErrno(errno);
     459    }
     460
     461    // Use large backlog, as otherwise local sockets can reject connection
     462    // attempts. Usually harmless, but causes an unnecessary start attempt
     463    // of IPCD (which will terminate straight away), and the next attempt
     464    // usually succeeds. But better avoid unnecessary activities.
     465    if (listen(pThis->fdListen, 128))
     466    {
     467        LogFlowFunc(("listen failed [%d]\n", errno));
     468        return RTErrConvertFromErrno(errno);
     469    }
     470
     471    // Increase the file table size to 10240 or as high as possible.
     472    struct rlimit lim;
     473    if (getrlimit(RLIMIT_NOFILE, &lim) == 0)
     474    {
     475        if (    lim.rlim_cur < 10240
     476            &&  lim.rlim_cur < lim.rlim_max)
     477        {
     478            lim.rlim_cur = lim.rlim_max <= 10240 ? lim.rlim_max : 10240;
     479            if (setrlimit(RLIMIT_NOFILE, &lim) == -1)
     480                LogFlowFunc(("WARNING: failed to increase file descriptor limit. (%d)\n", errno));
     481        }
     482    }
     483    else
     484        LogFlowFunc(("WARNING: failed to obtain per-process file-descriptor limit (%d).\n", errno));
     485
     486    int vrc = RTSocketFromNative(&pThis->hSockListen, pThis->fdListen);
     487    if (RT_FAILURE(vrc))
     488    {
     489        LogFlowFunc(("RTSocketFromNative() -> %Rrc\n", vrc));
     490        return vrc;
     491    }
     492
     493    pThis->fdListen = (int)RTSocketToNative(pThis->hSockListen);
     494
     495    vrc = RTPollSetCreate(&pThis->hPollSet);
     496    if (RT_FAILURE(vrc))
     497    {
     498        LogFlowFunc(("RTPollSetCreate() -> %Rrc\n", vrc));
     499        return vrc;
     500    }
     501
     502    g_hPollSet = pThis->hPollSet;
     503
     504    vrc = RTPollSetAddSocket(pThis->hPollSet, pThis->hSockListen, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, UINT32_MAX - 1);
     505    if (RT_FAILURE(vrc))
     506    {
     507        LogFlowFunc(("RTPollSetAddSocket() -> %Rrc\n", vrc));
     508        return vrc;
     509    }
     510
     511    return VINF_SUCCESS;
     512}
     513
     514
     515static void ipcdTerm(PIPCDSTATE pThis)
     516{
     517    Assert(pThis->ipcClientCount == 0);
     518
     519    // it is critical that we release the lock before closing the socket,
     520    // otherwise, a client might launch another daemon that would be unable
     521    // to acquire the lock and would then leave the client without a daemon.
     522
     523    // deleting directory and files underneath it allows another process
     524    // to think it has exclusive access.  better to just leave the hidden
     525    // directory in /tmp and let the OS clean it up via the usual tmpdir
     526    // cleanup cron job.
     527
     528    // this removes the advisory lock, allowing other processes to acquire it.
     529    if (pThis->ipcLockFD) {
     530        close(pThis->ipcLockFD);
     531        pThis->ipcLockFD = 0;
     532    }
     533
     534    int vrc = VINF_SUCCESS;
     535    if (pThis->hPollSet != NIL_RTPOLLSET)
     536    {
     537        vrc = RTPollSetDestroy(pThis->hPollSet);
     538        AssertRC(vrc);
     539        pThis->hPollSet = NIL_RTPOLLSET;
     540    }
     541
     542    if (pThis->hSockListen != NIL_RTSOCKET)
     543    {
     544        vrc = RTSocketClose(pThis->hSockListen);
     545        AssertRC(vrc);
     546        pThis->hSockListen = NIL_RTSOCKET;
     547    }
     548}
     549
     550
     551//-----------------------------------------------------------------------------
     552#ifndef VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC
    429553int main(int argc, char **argv)
    430554{
     
    482606    //IPC_Sleep(2);
    483607
    484     struct sockaddr_un addr;
    485     memset(&addr, 0, sizeof(addr));
    486     addr.sun_family = AF_UNIX;
    487 
    488     // set socket address
    489     if (!pszSocketPath)
    490         IPC_GetDefaultSocketPath(addr.sun_path, sizeof(addr.sun_path));
    491     else
    492         RTStrCopy(addr.sun_path, sizeof(addr.sun_path), pszSocketPath);
    493 
    494 #ifdef IPC_USE_FILE_LOCK
    495     Status status = InitDaemonDir(addr.sun_path);
    496     if (status != EOk) {
    497         if (status == ELockFileLock) {
    498             LogFlowFunc(("Another daemon is already running, exiting.\n"));
    499             // send a signal to the blocked parent to indicate success
    500             IPC_NotifyParent(uStartupPipeFd);
    501             return 0;
    502         }
    503         else {
    504             LogFlowFunc(("InitDaemonDir failed (status=%d)\n", status));
    505             // don't notify the parent to cause it to fail in PR_Read() after
    506             // we terminate
    507             if (status != ELockFileOwner)
    508                 printf("Cannot create a lock file for '%s'.\n"
    509                         "Check permissions.\n", addr.sun_path);
    510             return 0;
    511         }
    512     }
     608    IPCDSTATE IpcdState;
     609    vrc = ipcdInit(&IpcdState, pszSocketPath);
     610    if (vrc == VERR_ALREADY_EXISTS)
     611    {
     612        IPC_NotifyParent(uStartupPipeFd);
     613        return 0;
     614    }
     615
     616    if (RT_SUCCESS(vrc))
     617    {
     618        IPC_NotifyParent(uStartupPipeFd);
     619        PollLoop(&IpcdState);
     620    }
     621
     622    ipcdTerm(&IpcdState);
     623    return 0;
     624}
     625
     626#else
     627
     628static DECLCALLBACK(int) ipcdThread(RTTHREAD hThreadSelf, void *pvUser)
     629{
     630    IPCDSTATE IpcdState;
     631
     632    int vrc = ipcdInit(&IpcdState, NULL /*pszSocketPath*/);
     633    *(int *)pvUser = vrc; /* Set the startup status code. */
     634    RTThreadUserSignal(hThreadSelf);
     635
     636    if (RT_SUCCESS(vrc))
     637        PollLoop(&IpcdState);
     638
     639    ipcdTerm(&IpcdState);
     640    return VINF_SUCCESS;
     641}
     642
     643
     644DECL_EXPORT_NOTHROW(int) RTCALL VBoxXpcomIpcdCreate(PRTTHREAD phThrdIpcd)
     645{
     646    int vrcThrdStartup = VINF_SUCCESS;
     647    int vrc = RTThreadCreate(phThrdIpcd, ipcdThread, &vrcThrdStartup, 0 /*cbStack*/, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "IPCD-Msg");
     648    if (RT_FAILURE(vrc))
     649        return vrc;
     650
     651    vrc = RTThreadUserWait(*phThrdIpcd, RT_MS_30SEC);
     652    AssertRCReturn(vrc, vrc);
     653
     654    if (RT_FAILURE(vrcThrdStartup))
     655    {
     656        /* Wait for the thread to terminate. */
     657        vrc = RTThreadWait(*phThrdIpcd, RT_MS_30SEC, NULL /*prc*/);
     658        AssertRC(vrc);
     659        *phThrdIpcd = NIL_RTTHREAD;
     660        LogFlowFunc(("Creating daemon failed -> %Rrc\n", vrcThrdStartup));
     661        return vrcThrdStartup;
     662    }
     663
     664    return VINF_SUCCESS;
     665}
     666
     667
     668DECL_EXPORT_NOTHROW(int) RTCALL VBoxXpcomIpcdDestroy(RTTHREAD hThrdIpcd)
     669{
     670    /* Normally just need to wait as this will get called when the last client has exited and VBoxSVC is shutting down. */
     671    int vrcThrd = VINF_SUCCESS;
     672    int vrc = RTThreadWait(hThrdIpcd, RT_MS_30SEC, &vrcThrd);
     673    if (RT_FAILURE(vrc))
     674        return vrc;
     675
     676    return vrcThrd;
     677}
    513678#endif
    514 
    515     int fdListen = socket(PF_UNIX, SOCK_STREAM, 0);
    516     if (fdListen == -1)
    517         LogFlowFunc(("socket failed [%d]\n", errno));
    518     else
    519     {
    520         if (bind(fdListen, (struct sockaddr *)&addr, sizeof(addr)) == 0)
    521         {
    522             // Use large backlog, as otherwise local sockets can reject connection
    523             // attempts. Usually harmless, but causes an unnecessary start attempt
    524             // of IPCD (which will terminate straight away), and the next attempt
    525             // usually succeeds. But better avoid unnecessary activities.
    526             if (listen(fdListen, 128) == 0)
    527             {
    528                 IPC_NotifyParent(uStartupPipeFd);
    529 
    530 #if defined(VBOX) && !defined(XP_OS2)
    531                 // Increase the file table size to 10240 or as high as possible.
    532                 struct rlimit lim;
    533                 if (getrlimit(RLIMIT_NOFILE, &lim) == 0)
    534                 {
    535                     if (    lim.rlim_cur < 10240
    536                         &&  lim.rlim_cur < lim.rlim_max)
    537                     {
    538                         lim.rlim_cur = lim.rlim_max <= 10240 ? lim.rlim_max : 10240;
    539                         if (setrlimit(RLIMIT_NOFILE, &lim) == -1)
    540                             printf("WARNING: failed to increase file descriptor limit. (%d)\n", errno);
    541                     }
    542                 }
    543                 else
    544                     printf("WARNING: failed to obtain per-process file-descriptor limit (%d).\n", errno);
    545 #endif
    546 
    547                 RTSOCKET hSockListen;
    548                 int vrc = RTSocketFromNative(&hSockListen, fdListen);
    549                 if (RT_SUCCESS(vrc))
    550                 {
    551                     fdListen = (int)RTSocketToNative(hSockListen);
    552 
    553                     RTPOLLSET hPollSet = NIL_RTPOLLSET;
    554                     vrc = RTPollSetCreate(&hPollSet);
    555                     if (RT_SUCCESS(vrc))
    556                     {
    557                         g_hPollSet = hPollSet;
    558 
    559                         vrc = RTPollSetAddSocket(hPollSet, hSockListen, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, UINT32_MAX - 1);
    560                         if (RT_SUCCESS(vrc))
    561                             PollLoop(hPollSet, fdListen);
    562                         else
    563                             LogFlowFunc(("RTPollSetCreate() -> %Rrc\n", vrc));
    564                     }
    565                     else
    566                         LogFlowFunc(("RTPollSetCreate() -> %Rrc\n", vrc));
    567 
    568                     vrc = RTPollSetDestroy(hPollSet);
    569                     AssertRC(vrc);
    570                 }
    571                 else
    572                     LogFlowFunc(("RTSocketFromNative() -> %Rrc\n", vrc));
    573 
    574                 vrc = RTSocketClose(hSockListen);
    575                 AssertRC(vrc);
    576                 fdListen = -1;
    577             }
    578             else
    579                 LogFlowFunc(("listen failed [%d]\n", errno));
    580         }
    581         else
    582             LogFlowFunc(("bind failed [%d]\n", errno));
    583 
    584         LogFlowFunc(("closing socket\n"));
    585         if (fdListen != -1)
    586             close(fdListen);
    587     }
    588 
    589     //IPC_Sleep(5);
    590 
    591 #ifdef IPC_USE_FILE_LOCK
    592     // it is critical that we release the lock before closing the socket,
    593     // otherwise, a client might launch another daemon that would be unable
    594     // to acquire the lock and would then leave the client without a daemon.
    595 
    596     ShutdownDaemonDir();
    597 #endif
    598 
    599     return 0;
    600 }
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