VirtualBox

Ignore:
Timestamp:
Feb 20, 2008 4:18:29 PM (17 years ago)
Author:
vboxsync
Message:

XPCOM/IPC: Cleaned up IPC daemon startup procedure (makes sure there are no incorrect failure assertions when another copy of the daemon is already running).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcdUnix.cpp

    r6540 r7049  
    8787#endif
    8888
    89 #ifdef VBOX
    90 static PRBool fatal = PR_FALSE;
    91 #endif
    92 
    9389#ifdef IPC_USE_FILE_LOCK
    9490
     91enum Status
     92{
     93    EOk = 0,
     94    ELockFileOpen = -1,
     95    ELockFileLock = -2,
     96
     97};
     98
    9599static int ipcLockFD = 0;
    96100
    97 static PRBool AcquireDaemonLock(const char *baseDir)
     101static Status AcquireDaemonLock(const char *baseDir)
    98102{
    99103    const char lockName[] = "lock";
     
    117121
    118122    if (ipcLockFD == -1)
    119 #ifdef VBOX
    120     {
    121         // cannot open file --> this is fatal
    122         fatal = PR_TRUE;
    123 #endif
    124         return PR_FALSE;
    125 #ifdef VBOX
    126     }
    127 #endif
     123        return ELockFileOpen;
    128124
    129125    //
     
    139135    lock.l_whence = SEEK_SET;
    140136    if (fcntl(ipcLockFD, F_SETLK, &lock) == -1)
    141 #ifdef VBOX
    142         // cannot grab file lock --> this is NOT fatal (other daemon running)
    143 #endif
    144         return PR_FALSE;
     137        return ELockFileLock;
    145138
    146139    //
     
    157150    write(ipcLockFD, buf, nb);
    158151
    159     return PR_TRUE;
    160 }
    161 
    162 static PRBool InitDaemonDir(const char *socketPath)
     152    return EOk;
     153}
     154
     155static Status InitDaemonDir(const char *socketPath)
    163156{
    164157    LOG(("InitDaemonDir [sock=%s]\n", socketPath));
     
    178171    // must be active, so bail.
    179172    //
    180     PRBool haveLock = AcquireDaemonLock(baseDir);
     173    Status status = AcquireDaemonLock(baseDir);
    181174
    182175    PL_strfree(baseDir);
    183176
    184     if (haveLock) {
     177    if (status == EOk) {
    185178        // delete an existing socket to prevent bind from failing.
    186179        unlink(socketPath);
    187180    }
    188     return haveLock;
     181    return status;
    189182}
    190183
     
    402395    PRFileDesc *listenFD = NULL;
    403396    PRNetAddr addr;
    404 #ifdef VBOX
    405     enum { None=0, Directory, All } successLevel = None;
    406 #endif
    407397
    408398    //
     
    431421
    432422#ifdef IPC_USE_FILE_LOCK
    433     if (!InitDaemonDir(addr.local.path)) {
    434         LOG(("InitDaemonDir failed\n"));
     423    Status status = InitDaemonDir(addr.local.path);
     424    if (status != EOk) {
     425        if (status == ELockFileLock) {
     426            LOG(("Another daemon is already running, exiting.\n"));
     427            // send a signal to the blocked parent to indicate success
     428            IPC_NotifyParent();
     429            return 0;
     430        }
     431        else {
     432            LOG(("InitDaemonDir failed (status=%d)\n", status));
     433            // don't notify the parent to cause it to fail in PR_Read() after
     434            // we terminate
    435435#ifdef VBOX
    436         printf("Cannot create/open directory '%s'\n", addr.local.path);
     436            printf("Cannot create a lock file for '%s'.\n"
     437                   "Check permissions.\n", addr.local.path);
    437438#endif
    438         goto end;
    439     }
    440 #endif
    441 
    442 #ifdef VBOX
    443     successLevel = Directory;
     439            return 0;
     440        }
     441    }
    444442#endif
    445443
     
    447445    if (!listenFD) {
    448446        LOG(("PR_OpenTCPSocket failed [%d]\n", PR_GetError()));
    449         goto end;
    450     }
    451 
    452     if (PR_Bind(listenFD, &addr) != PR_SUCCESS) {
     447    }
     448    else if (PR_Bind(listenFD, &addr) != PR_SUCCESS) {
    453449        LOG(("PR_Bind failed [%d]\n", PR_GetError()));
    454         goto end;
    455     }
    456 
    457     IPC_InitModuleReg(argv[0]);
    458 
    459     if (PR_Listen(listenFD, 5) != PR_SUCCESS) {
    460         LOG(("PR_Listen failed [%d]\n", PR_GetError()));
    461         goto end;
    462     }
    463 
    464     IPC_NotifyParent();
    465 
    466 #ifdef VBOX
    467     /* redirect all standard file descriptors to /dev/null for daemonizing */
    468     PR_Close(PR_STDIN);
    469     PR_Open("/dev/null", O_RDONLY, 0);
    470     PR_Close(PR_STDOUT);
    471     PR_Open("/dev/null", O_WRONLY, 0);
    472     PR_Close(PR_STDERR);
    473     PR_Open("/dev/null", O_WRONLY, 0);
    474 #endif
    475 
    476 #ifdef VBOX
    477     successLevel = All;
    478 #endif
    479 
    480     PollLoop(listenFD);
    481 
    482 end:
    483 #ifdef VBOX
    484     if (successLevel >= All)
    485 #endif
    486     IPC_ShutdownModuleReg();
    487 
    488 #ifdef VBOX
    489     if (successLevel >= All)
    490 #endif
    491     IPC_NotifyParent();
     450    }
     451    else {
     452        IPC_InitModuleReg(argv[0]);
     453
     454        if (PR_Listen(listenFD, 5) != PR_SUCCESS) {
     455            LOG(("PR_Listen failed [%d]\n", PR_GetError()));
     456        }
     457        else {
     458            // redirect all standard file descriptors to /dev/null for
     459            // proper daemonizing
     460            PR_Close(PR_STDIN);
     461            PR_Open("/dev/null", O_RDONLY, 0);
     462            PR_Close(PR_STDOUT);
     463            PR_Open("/dev/null", O_WRONLY, 0);
     464            PR_Close(PR_STDERR);
     465            PR_Open("/dev/null", O_WRONLY, 0);
     466
     467            IPC_NotifyParent();
     468
     469            PollLoop(listenFD);
     470        }
     471
     472        IPC_ShutdownModuleReg();
     473    }
    492474
    493475    //IPC_Sleep(5);
     
    498480    // to acquire the lock and would then leave the client without a daemon.
    499481
    500 #ifdef VBOX
    501     if (successLevel >= Directory)
    502 #endif
    503482    ShutdownDaemonDir();
    504483#endif
     
    509488    }
    510489
    511 #ifdef VBOX
    512     if (successLevel < All)
    513     {
    514         if (fatal)
    515         {
    516             /* Kill the parent which spawned us */
    517             printf("Abnormal termination.\n");
    518             kill(getppid(), SIGINT);
    519         }
    520     }
    521 #endif
    522 
    523490    return 0;
    524491}
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