VirtualBox

Ignore:
Timestamp:
Oct 7, 2010 4:36:21 PM (14 years ago)
Author:
vboxsync
Message:

Runtime/Process: Solaris: put every detached process in its own process contract so that independent processes don't get killed if some service is terminated

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/posix/process-posix.cpp

    r30312 r32990  
    5353# include <mach-o/dyld.h>
    5454#endif
     55#ifdef RT_OS_SOLARIS
     56# include <limits.h>
     57# include <sys/ctfs.h>
     58# include <sys/contract/process.h>
     59# include <libcontract.h>
     60#endif
    5561
    5662#include <iprt/process.h>
     
    134140#endif
    135141}
     142
     143
     144#ifdef RT_OS_SOLARIS
     145/** @todo the error reporting of the Solaris process contract code could be
     146 * a lot better, but essentially it is not meant to run into errors after
     147 * the debugging phase. */
     148static int rtSolarisContractPreFork(void)
     149{
     150    int templateFd = open64(CTFS_ROOT "/process/template", O_RDWR);
     151    if (templateFd < 0)
     152        return -1;
     153
     154    /* Set template parameters and event sets. */
     155    if (ct_pr_tmpl_set_param(templateFd, CT_PR_PGRPONLY))
     156    {
     157        close(templateFd);
     158        return -1;
     159    }
     160    if (ct_pr_tmpl_set_fatal(templateFd, CT_PR_EV_HWERR))
     161    {
     162        close(templateFd);
     163        return -1;
     164    }
     165    if (ct_tmpl_set_critical(templateFd, 0))
     166    {
     167        close(templateFd);
     168        return -1;
     169    }
     170    if (ct_tmpl_set_informative(templateFd, CT_PR_EV_HWERR))
     171    {
     172        close(templateFd);
     173        return -1;
     174    }
     175
     176    /* Make this the active template for the process. */
     177    if (ct_tmpl_activate(templateFd))
     178    {
     179        close(templateFd);
     180        return -1;
     181    }
     182
     183    return templateFd;
     184}
     185
     186static void rtSolarisContractPostForkChild(int templateFd)
     187{
     188    if (templateFd == -1)
     189        return;
     190
     191    /* Clear the active template. */
     192    ct_tmpl_clear(templateFd);
     193    close(templateFd);
     194}
     195
     196static void rtSolarisContractPostForkParent(int templateFd, pid_t pid)
     197{
     198    if (templateFd == -1)
     199        return;
     200
     201    /* Clear the active template. */
     202    int cleared = ct_tmpl_clear(templateFd);
     203    close(templateFd);
     204
     205    /* If the clearing failed or the fork failed there's nothing more to do. */
     206    if (cleared || pid <= 0)
     207        return;
     208
     209    /* Look up the contract which was created by this thread. */
     210    int statFd = open64(CTFS_ROOT "/process/latest", O_RDONLY);
     211    if (statFd == -1)
     212        return;
     213    ct_stathdl_t statHdl;
     214    if (ct_status_read(statFd, CTD_COMMON, &statHdl))
     215    {
     216        close(statFd);
     217        return;
     218    }
     219    ctid_t ctId = ct_status_get_id(statHdl);
     220    ct_status_free(statHdl);
     221    close(statFd);
     222    if (ctId < 0)
     223        return;
     224
     225    /* Abandon this contract we just created. */
     226    char ctlPath[PATH_MAX];
     227    size_t len = snprintf(ctlPath, sizeof(ctlPath),
     228                          CTFS_ROOT "/process/%d/ctl", ctId);
     229    if (len >= sizeof(ctlPath))
     230        return;
     231    int ctlFd = open64(ctlPath, O_WRONLY);
     232    if (statFd == -1)
     233        return;
     234    if (ct_ctl_abandon(ctlFd) < 0)
     235    {
     236        close(ctlFd);
     237        return;
     238    }
     239    close(ctlFd);
     240}
     241
     242#endif /* RT_OS_SOLARIS */
    136243
    137244
     
    327434#endif
    328435    {
     436#ifdef RT_OS_SOLARIS
     437        int templateFd = rtSolarisContractPreFork();
     438        if (templateFd == -1)
     439            return VERR_OPEN_FAILED;
     440#endif /* RT_OS_SOLARIS */
    329441        pid = fork();
    330442        if (!pid)
    331443        {
     444#ifdef RT_OS_SOLARIS
     445            rtSolarisContractPostForkChild(templateFd);
     446#endif /* RT_OS_SOLARIS */
    332447            setpgid(0, 0); /* see comment above */
    333448
     
    404519            exit(127);
    405520        }
     521#ifdef RT_OS_SOLARIS
     522        rtSolarisContractPostForkParent(templateFd, pid);
     523#endif /* RT_OS_SOLARIS */
    406524        if (pid > 0)
    407525        {
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