예제 #1
0
void VerifyEnvironmentsPromise(Promise *pp)
{
    Attributes a = { {0} };
    CfLock thislock;
    Promise *pexp;

    a = GetEnvironmentsAttributes(pp);

    if (EnvironmentsSanityChecks(a, pp))
    {
        thislock = AcquireLock("virtual", VUQNAME, CFSTARTTIME, a, pp, false);

        if (thislock.lock == NULL)
        {
            return;
        }

        CF_OCCUR++;

        PromiseBanner(pp);
        NewScalar("this", "promiser", pp->promiser, cf_str);

        pexp = ExpandDeRefPromise("this", pp);
        VerifyEnvironments(a, pp);
        DeletePromise(pexp);
    }

    YieldCurrentLock(thislock);
}
예제 #2
0
void TestExpandPromise(const ReportContext *report_context)
{
    Promise pp = { 0 }, *pcopy;

    printf("%d. Testing promise duplication and expansion\n", ++NR);
    pp.promiser = "the originator";
    pp.promisee = (Rval) {
        "the recipient", CF_SCALAR
    };
    pp.classes = "upper classes";
    pp.offset.line = 12;
    pp.audit = NULL;
    pp.conlist = NULL;

    pp.bundletype = "bundle_type";
    pp.bundle = "test_bundle";
    pp.ref = "commentary";
    pp.agentsubtype = NULL;
    pp.done = false;
    pp.next = NULL;
    pp.cache = NULL;
    pp.inode_cache = NULL;
    pp.this_server = NULL;
    pp.donep = &(pp.done);
    pp.conn = NULL;

    ConstraintAppendToPromise(&pp, "lval1", (Rval) {
        xstrdup("rval1"), CF_SCALAR
    }, "lower classes1", false);
    ConstraintAppendToPromise(&pp, "lval2", (Rval) {
        xstrdup("rval2"), CF_SCALAR
    }, "lower classes2", false);

//getuid ConstraintAppendToPromise(&pp,"lval2",,CF_SCALAR,"lower classes2");

    /* Now copy promise and delete */

    pcopy = DeRefCopyPromise("diagnostic-scope", &pp);
    if (VERBOSE || DEBUG)
    {
        printf("-----------------------------------------------------------\n");
        printf("Raw test promises\n\n");
        ShowPromise(report_context, REPORT_OUTPUT_TYPE_TEXT, &pp, 4);
        ShowPromise(report_context, REPORT_OUTPUT_TYPE_HTML, &pp, 4);

        ShowPromise(report_context, REPORT_OUTPUT_TYPE_TEXT, pcopy, 6);
        ShowPromise(report_context, REPORT_OUTPUT_TYPE_HTML, pcopy, 6);
    }
    DeletePromise(pcopy);
}
예제 #3
0
int main(int argc, char *argv[])
{
    Rlist *rp;
    Promise *pp;
#if !defined(__MINGW32__)
    int count = 0;
    int status;
    int pid;
#endif

    GenericAgentConfig *config = CheckOpts(argc, argv);
    ReportContext *report_context = OpenReports("runagent");

    Policy *policy = GenericInitialize("runagent", config, report_context);
    ThisAgentInit();
    KeepControlPromises(policy);      // Set RUNATTR using copy

    if (BACKGROUND && INTERACTIVE)
    {
        CfOut(cf_error, "", " !! You cannot specify background mode and interactive mode together");
        exit(1);
    }

    pp = MakeDefaultRunAgentPromise();

/* HvB */
    if (HOSTLIST)
    {
        rp = HOSTLIST;

        while (rp != NULL)
        {

#ifdef __MINGW32__
            if (BACKGROUND)
            {
                CfOut(cf_verbose, "",
                      "Windows does not support starting processes in the background - starting in foreground");
                BACKGROUND = false;
            }
#else
            if (BACKGROUND)     /* parallel */
            {
                if (count <= MAXCHILD)
                {
                    if (fork() == 0)    /* child process */
                    {
                        HailServer(rp->item, RUNATTR, pp);
                        exit(0);
                    }
                    else        /* parent process */
                    {
                        rp = rp->next;
                        count++;
                    }
                }
                else
                {
                    pid = wait(&status);
                    CfDebug("child = %d, child number = %d\n", pid, count);
                    count--;
                }
            }
            else                /* serial */
#endif /* __MINGW32__ */
            {
                HailServer(rp->item, RUNATTR, pp);
                rp = rp->next;
            }
        }                       /* end while */
    }                           /* end if HOSTLIST */

#ifndef __MINGW32__
    if (BACKGROUND)
    {
        printf("Waiting for child processes to finish\n");
        while (count > 1)
        {
            pid = wait(&status);
            CfOut(cf_verbose, "", "Child = %d ended, number = %d\n", pid, count);
            count--;
        }
    }
#endif

    DeletePromise(pp);

    GenericAgentConfigDestroy(config);
    ReportContextDestroy(report_context);

    return 0;
}
예제 #4
0
파일: cf-execd.c 프로젝트: pombredanne/core
/* Might be called back from NovaWin_StartExecService */
void StartServer(Policy *policy, ExecConfig *config, const ReportContext *report_context)
{
#if !defined(__MINGW32__)
    time_t now = time(NULL);
#endif
    Promise *pp = NewPromise("exec_cfengine", "the executor agent");
    Attributes dummyattr;
    CfLock thislock;

#if defined(HAVE_PTHREAD)
    pthread_attr_init(&threads_attrs);
    pthread_attr_setdetachstate(&threads_attrs, PTHREAD_CREATE_DETACHED);
    pthread_attr_setstacksize(&threads_attrs, (size_t)2048*1024);
#endif

    Banner("Starting executor");
    memset(&dummyattr, 0, sizeof(dummyattr));

    dummyattr.restart_class = "nonce";
    dummyattr.transaction.ifelapsed = CF_EXEC_IFELAPSED;
    dummyattr.transaction.expireafter = CF_EXEC_EXPIREAFTER;

    if (!ONCE)
    {
        thislock = AcquireLock(pp->promiser, VUQNAME, CFSTARTTIME, dummyattr, pp, false);

        if (thislock.lock == NULL)
        {
            DeletePromise(pp);
            return;
        }

        /* Kill previous instances of cf-execd if those are still running */
        Apoptosis();

        /* FIXME: kludge. This code re-sets "last" lock to the one we have
           acquired a few lines before. If the cf-execd is terminated, this lock
           will be removed, and subsequent restart of cf-execd won't fail.

           The culprit is Apoptosis(), which creates a promise and executes it,
           taking locks during it, so CFLOCK/CFLAST/CFLOG get reset.

           Proper fix is to keep all the taken locks in the memory, and release
           all of them during process termination.
         */
        strcpy(CFLOCK, thislock.lock);
        strcpy(CFLAST, thislock.last ? thislock.last : "");
        strcpy(CFLOG, thislock.log ? thislock.log : "");
    }

#ifdef MINGW

    if (!NO_FORK)
    {
        CfOut(cf_verbose, "", "Windows does not support starting processes in the background - starting in foreground");
    }

#else /* NOT MINGW */

    if ((!NO_FORK) && (fork() != 0))
    {
        CfOut(cf_inform, "", "cf-execd starting %.24s\n", cf_ctime(&now));
        _exit(0);
    }

    if (!NO_FORK)
    {
        ActAsDaemon(0);
    }

#endif /* NOT MINGW */

    WritePID("cf-execd.pid");
    signal(SIGINT, HandleSignals);
    signal(SIGTERM, HandleSignals);
    signal(SIGHUP, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    signal(SIGUSR1, HandleSignals);
    signal(SIGUSR2, HandleSignals);

    umask(077);

    if (ONCE)
    {
        CfOut(cf_verbose, "", "Sleeping for splaytime %d seconds\n\n", SPLAYTIME);
        sleep(SPLAYTIME);
        LocalExec(config);
        CloseLog();
    }
    else
    {
        while (true)
        {
            if (ScheduleRun(&policy, config, report_context))
            {
                CfOut(cf_verbose, "", "Sleeping for splaytime %d seconds\n\n", SPLAYTIME);
                sleep(SPLAYTIME);

#if defined(HAVE_PTHREAD)
                if (!LocalExecInThread(config))
                {
                    CfOut(cf_inform, "", "Unable to run agent in thread, falling back to blocking execution");
#endif
                    LocalExec(config);
#if defined(HAVE_PTHREAD)
                }
#endif
            }
        }
    }

    if (!ONCE)
    {
        YieldCurrentLock(thislock);
    }
}