Beispiel #1
0
static PromiseResult VerifyProcessOp(EvalContext *ctx, Item *procdata, Attributes a, const Promise *pp)
{
    bool do_signals = true;
    int out_of_range;
    int killed = 0;
    bool need_to_restart = true;
    Item *killlist = NULL;

    int matches = FindPidMatches(procdata, &killlist, a, pp->promiser);

/* promise based on number of matches */

    PromiseResult result = PROMISE_RESULT_NOOP;
    if (a.process_count.min_range != CF_NOINT)  /* if a range is specified */
    {
        if ((matches < a.process_count.min_range) || (matches > a.process_count.max_range))
        {
            cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, a, "Process count for '%s' was out of promised range (%d found)", pp->promiser, matches);
            result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE);
            for (const Rlist *rp = a.process_count.out_of_range_define; rp != NULL; rp = rp->next)
            {
                ClassRef ref = ClassRefParse(RlistScalarValue(rp));
                EvalContextClassPutSoft(ctx, RlistScalarValue(rp), CONTEXT_SCOPE_NAMESPACE, "source=promise");
                ClassRefDestroy(ref);
            }
            out_of_range = true;
        }
        else
        {
            for (const Rlist *rp = a.process_count.in_range_define; rp != NULL; rp = rp->next)
            {
                ClassRef ref = ClassRefParse(RlistScalarValue(rp));
                EvalContextClassPutSoft(ctx, RlistScalarValue(rp), CONTEXT_SCOPE_NAMESPACE, "source=promise");
                ClassRefDestroy(ref);
            }
            cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Process promise for '%s' is kept", pp->promiser);
            out_of_range = false;
        }
    }
    else
    {
        out_of_range = true;
    }

    if (!out_of_range)
    {
        DeleteItemList(killlist);
        return result;
    }

    if (a.transaction.action == cfa_warn)
    {
        do_signals = false;
        result = PromiseResultUpdate(result, PROMISE_RESULT_WARN);
    }
    else
    {
        do_signals = true;
    }

/* signal/kill promises for existing matches */

    if (do_signals && (matches > 0))
    {
        if (a.process_stop != NULL)
        {
            if (DONTDO)
            {
                cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_WARN, pp, a,
                     "Need to keep process-stop promise for '%s', but only a warning is promised", pp->promiser);
                result = PromiseResultUpdate(result, PROMISE_RESULT_WARN);
            }
            else
            {
                if (IsExecutable(CommandArg0(a.process_stop)))
                {
                    ShellCommandReturnsZero(a.process_stop, SHELL_TYPE_NONE);
                }
                else
                {
                    cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a,
                         "Process promise to stop '%s' could not be kept because '%s' the stop operator failed",
                         pp->promiser, a.process_stop);
                    result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL);
                    DeleteItemList(killlist);
                    return result;
                }
            }
        }

        killed = DoAllSignals(ctx, killlist, a, pp, &result);
    }

/* delegated promise to restart killed or non-existent entries */

    need_to_restart = (a.restart_class != NULL) && (killed || (matches == 0));

    DeleteItemList(killlist);

    if (!need_to_restart)
    {
        cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "No restart promised for %s", pp->promiser);
        return result;
    }
    else
    {
        if (a.transaction.action == cfa_warn)
        {
            cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_WARN, pp, a,
                 "Need to keep restart promise for '%s', but only a warning is promised", pp->promiser);
            result = PromiseResultUpdate(result, PROMISE_RESULT_WARN);
        }
        else
        {
            cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Making a one-time restart promise for '%s'", pp->promiser);
            result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE);
            EvalContextClassPutSoft(ctx, a.restart_class, CONTEXT_SCOPE_NAMESPACE, "source=promise");
        }
    }

    return result;
}
Beispiel #2
0
static void VerifyProcessOp(EvalContext *ctx, Item *procdata, Attributes a, Promise *pp)
{
    int matches = 0, do_signals = true, out_of_range, killed = 0, need_to_restart = true;
    Item *killlist = NULL;

    matches = FindPidMatches(ctx, procdata, &killlist, a, pp->promiser);

/* promise based on number of matches */

    if (a.process_count.min_range != CF_NOINT)  /* if a range is specified */
    {
        if ((matches < a.process_count.min_range) || (matches > a.process_count.max_range))
        {
            cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, a, "Process count for '%s' was out of promised range (%d found)", pp->promiser, matches);
            for (const Rlist *rp = a.process_count.out_of_range_define; rp != NULL; rp = rp->next)
            {
                if (!EvalContextHeapContainsSoft(ctx, rp->item))
                {
                    EvalContextHeapAddSoft(ctx, rp->item, PromiseGetNamespace(pp));
                }
            }
            out_of_range = true;
        }
        else
        {
            for (const Rlist *rp = a.process_count.in_range_define; rp != NULL; rp = rp->next)
            {
                if (!EvalContextHeapContainsSoft(ctx, rp->item))
                {
                    EvalContextHeapAddSoft(ctx, rp->item, PromiseGetNamespace(pp));
                }
            }
            cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Process promise for '%s' is kept", pp->promiser);
            out_of_range = false;
        }
    }
    else
    {
        out_of_range = true;
    }

    if (!out_of_range)
    {
        return;
    }

    if (a.transaction.action == cfa_warn)
    {
        do_signals = false;
    }
    else
    {
        do_signals = true;
    }

/* signal/kill promises for existing matches */

    if (do_signals && (matches > 0))
    {
        if (a.process_stop != NULL)
        {
            if (DONTDO)
            {
                cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_WARN, pp, a,
                     "Need to keep process-stop promise for '%s', but only a warning is promised", pp->promiser);
            }
            else
            {
                if (IsExecutable(CommandArg0(a.process_stop)))
                {
                    ShellCommandReturnsZero(a.process_stop, SHELL_TYPE_NONE);
                }
                else
                {
                    cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_FAIL, pp, a,
                         "Process promise to stop '%s' could not be kept because '%s' the stop operator failed",
                         pp->promiser, a.process_stop);
                    DeleteItemList(killlist);
                    return;
                }
            }
        }

        killed = DoAllSignals(ctx, killlist, a, pp);
    }

/* delegated promise to restart killed or non-existent entries */

    need_to_restart = (a.restart_class != NULL) && (killed || (matches == 0));

    DeleteItemList(killlist);

    if (!need_to_restart)
    {
        cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "No restart promised for %s", pp->promiser);
        return;
    }
    else
    {
        if (a.transaction.action == cfa_warn)
        {
            cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_WARN, pp, a,
                 "Need to keep restart promise for '%s', but only a warning is promised", pp->promiser);
        }
        else
        {
            cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Making a one-time restart promise for '%s'", pp->promiser);
            EvalContextHeapAddSoft(ctx, a.restart_class, PromiseGetNamespace(pp));
        }
    }
}
static void VerifyProcessOp(Item *procdata, Attributes a, Promise *pp)
{
    int matches = 0, do_signals = true, out_of_range, killed = 0, need_to_restart = true;
    Item *killlist = NULL;

    CfDebug("VerifyProcessOp\n");

    matches = FindPidMatches(procdata, &killlist, a, pp);

/* promise based on number of matches */

    if (a.process_count.min_range != CF_NOINT)  /* if a range is specified */
    {
        if (matches < a.process_count.min_range || matches > a.process_count.max_range)
        {
            cfPS(cf_error, CF_CHG, "", pp, a, " !! Process count for \'%s\' was out of promised range (%d found)\n",
                 pp->promiser, matches);
            AddEphemeralClasses(a.process_count.out_of_range_define);
            out_of_range = true;
        }
        else
        {
            AddEphemeralClasses(a.process_count.in_range_define);
            cfPS(cf_verbose, CF_NOP, "", pp, a, " -> Process promise for %s is kept", pp->promiser);
            out_of_range = false;
        }
    }
    else
    {
        out_of_range = true;
    }

    if (!out_of_range)
    {
        return;
    }

    if (a.transaction.action == cfa_warn)
    {
        do_signals = false;
    }
    else
    {
        do_signals = true;
    }

/* signal/kill promises for existing matches */

    if (do_signals && matches > 0)
    {
        if (a.process_stop != NULL)
        {
            if (DONTDO)
            {
                cfPS(cf_error, CF_WARN, "", pp, a,
                     " -- Need to keep process-stop promise for %s, but only a warning is promised", pp->promiser);
            }
            else
            {
                if (IsExecutable(GetArg0(a.process_stop)))
                {
                    ShellCommandReturnsZero(a.process_stop, false);
                }
                else
                {
                    cfPS(cf_verbose, CF_FAIL, "", pp, a,
                         "Process promise to stop %s could not be kept because %s the stop operator failed",
                         pp->promiser, a.process_stop);
                    DeleteItemList(killlist);
                    return;
                }
            }
        }

        killed = DoAllSignals(killlist, a, pp);
    }

/* delegated promise to restart killed or non-existent entries */

    need_to_restart = (a.restart_class != NULL) && (killed || matches == 0);

    DeleteItemList(killlist);

    if (!need_to_restart)
    {
        cfPS(cf_verbose, CF_NOP, "", pp, a, " -> No restart promised for %s\n", pp->promiser);
        return;
    }
    else
    {
        if (a.transaction.action == cfa_warn)
        {
            cfPS(cf_error, CF_WARN, "", pp, a,
                 " -- Need to keep restart promise for %s, but only a warning is promised", pp->promiser);
        }
        else
        {
            cfPS(cf_inform, CF_CHG, "", pp, a, " -> Making a one-time restart promise for %s", pp->promiser);
            NewClass(a.restart_class);
        }
    }
}