コード例 #1
0
Item *SelectProcesses(const Item *processes, const char *process_name, ProcessSelect a, bool attrselect)
{
    Item *result = NULL;

    if (processes == NULL)
    {
        return result;
    }

    char *names[CF_PROCCOLS];
    int start[CF_PROCCOLS];
    int end[CF_PROCCOLS];

    GetProcessColumnNames(processes->name, &names[0], start, end);

    pcre *rx = CompileRegex(process_name);
    if (rx)
    {
        /* TODO: use actual time of ps-run, as time(NULL) may be later. */
        time_t pstime = time(NULL);

        for (Item *ip = processes->next; ip != NULL; ip = ip->next)
        {
            int s, e;

            if (StringMatchWithPrecompiledRegex(rx, ip->name, &s, &e))
            {
                if (NULL_OR_EMPTY(ip->name))
                {
                    continue;
                }

                if (attrselect && !SelectProcess(ip->name, pstime, names, start, end, a))
                {
                    continue;
                }

                pid_t pid = ExtractPid(ip->name, names, end);

                if (pid == -1)
                {
                    Log(LOG_LEVEL_VERBOSE, "Unable to extract pid while looking for %s", process_name);
                    continue;
                }

                PrependItem(&result, ip->name, "");
                result->counter = (int)pid;
            }
        }

        pcre_free(rx);
    }

    for (int i = 0; i < CF_PROCCOLS; i++)
    {
        free(names[i]);
    }

    return result;
}
コード例 #2
0
ファイル: processes_select.c プロジェクト: atsaloli/core
bool IsProcessNameRunning(char *procNameRegex)
{
    char *colHeaders[CF_PROCCOLS];
    int start[CF_PROCCOLS] = { 0 };
    int end[CF_PROCCOLS] = { 0 };
    bool matched = false;
    int i;

    memset(colHeaders, 0, sizeof(colHeaders));

    if (PROCESSTABLE == NULL)
    {
        Log(LOG_LEVEL_ERR, "IsProcessNameRunning: PROCESSTABLE is empty");
        return false;
    }
    /* TODO: use actual time of ps-run, not time(NULL), which may be later. */
    time_t pstime = time(NULL);

    GetProcessColumnNames(PROCESSTABLE->name, colHeaders, start, end);

    for (const Item *ip = PROCESSTABLE->next; !matched && ip != NULL; ip = ip->next) // iterate over ps lines
    {
        char *lineSplit[CF_PROCCOLS];
        memset(lineSplit, 0, sizeof(lineSplit));

        if (NULL_OR_EMPTY(ip->name))
        {
            continue;
        }

        if (!SplitProcLine(ip->name, pstime, colHeaders, start, end,
                           PS_COLUMN_ALGORITHM[VPSHARDCLASS], lineSplit))
        {
            Log(LOG_LEVEL_ERR, "IsProcessNameRunning: Could not split process line '%s'", ip->name);
            goto loop_cleanup;
        }

        ApplyPlatformExtraTable(colHeaders, lineSplit);

        if (SelectProcRegexMatch("CMD", "COMMAND", procNameRegex, true, colHeaders, lineSplit))
        {
            matched = true;
        }

   loop_cleanup:
        for (i = 0; lineSplit[i] != NULL; i++)
        {
            free(lineSplit[i]);
        }
    }

    for (i = 0; colHeaders[i] != NULL; i++)
    {
        free(colHeaders[i]);
    }

    return matched;
}
コード例 #3
0
ファイル: processes_select.c プロジェクト: zined/core
bool IsProcessNameRunning(EvalContext *ctx, char *procNameRegex)
{
    char *colHeaders[CF_PROCCOLS];
    Item *ip;
    int start[CF_PROCCOLS] = { 0 };
    int end[CF_PROCCOLS] = { 0 };
    bool matched = false;
    int i;

    if (PROCESSTABLE == NULL)
    {
        Log(LOG_LEVEL_ERR, "IsProcessNameRunning: PROCESSTABLE is empty");
        return false;
    }

    GetProcessColumnNames(PROCESSTABLE->name, (char **) colHeaders, start, end);

    for (ip = PROCESSTABLE->next; ip != NULL; ip = ip->next)    // iterate over ps lines
    {
        char *lineSplit[CF_PROCCOLS];

        if (NULL_OR_EMPTY(ip->name))
        {
            continue;
        }

        if (!SplitProcLine(ip->name, colHeaders, start, end, lineSplit))
        {
            Log(LOG_LEVEL_ERR, "IsProcessNameRunning: Could not split process line '%s'", ip->name);
            continue;
        }

        if (SelectProcRegexMatch(ctx, "CMD", "COMMAND", procNameRegex, colHeaders, lineSplit))
        {
            matched = true;
            break;
        }

        i = 0;
        while (lineSplit[i] != NULL)
        {
            free(lineSplit[i]);
            i++;
        }
    }

    i = 0;
    while (colHeaders[i] != NULL)
    {
        free(colHeaders[i]);
        i++;
    }

    return matched;
}
コード例 #4
0
ファイル: processes_select.c プロジェクト: zined/core
Item *SelectProcesses(EvalContext *ctx, const Item *processes, const char *process_name, ProcessSelect a, bool attrselect)
{
    Item *result = NULL;

    if (processes == NULL)
    {
        return result;
    }

    char *names[CF_PROCCOLS];
    int start[CF_PROCCOLS];
    int end[CF_PROCCOLS];

    GetProcessColumnNames(processes->name, &names[0], start, end);

    for (Item *ip = processes->next; ip != NULL; ip = ip->next)
    {
        int s, e;

        if (BlockTextMatch(ctx, process_name, ip->name, &s, &e))
        {
            if (NULL_OR_EMPTY(ip->name))
            {
                continue;
            }

            if (attrselect && !SelectProcess(ctx, ip->name, names, start, end, a))
            {
                continue;
            }

            pid_t pid = ExtractPid(ip->name, names, end);

            if (pid == -1)
            {
                Log(LOG_LEVEL_VERBOSE, "Unable to extract pid while looking for %s", process_name);
                continue;
            }

            PrependItem(&result, ip->name, "");
            result->counter = (int)pid;
        }
    }

    for (int i = 0; i < CF_PROCCOLS; i++)
    {
        free(names[i]);
    }

    return result;
}
コード例 #5
0
ファイル: processes_select.c プロジェクト: nickanderson/core
Item *SelectProcesses(const char *process_name, const ProcessSelect *a, bool attrselect)
{
    assert(a != NULL);
    const Item *processes = PROCESSTABLE;
    Item *result = NULL;

    if (processes == NULL)
    {
        return result;
    }

    char *names[CF_PROCCOLS];
    int start[CF_PROCCOLS];
    int end[CF_PROCCOLS];

    GetProcessColumnNames(processes->name, names, start, end);

    /* TODO: use actual time of ps-run, as time(NULL) may be later. */
    time_t pstime = time(NULL);

    for (Item *ip = processes->next; ip != NULL; ip = ip->next)
    {
        if (NULL_OR_EMPTY(ip->name))
        {
            continue;
        }

        if (!SelectProcess(ip->name, pstime, names, start, end, process_name, a, attrselect))
        {
            continue;
        }

        pid_t pid = ExtractPid(ip->name, names, end);

        if (pid == -1)
        {
            Log(LOG_LEVEL_VERBOSE, "Unable to extract pid while looking for %s", process_name);
            continue;
        }

        PrependItem(&result, ip->name, "");
        result->counter = (int)pid;
    }

    for (int i = 0; i < CF_PROCCOLS; i++)
    {
        free(names[i]);
    }

    return result;
}
コード例 #6
0
bool IsProcessNameRunning(char *procNameRegex)
{
    char *colHeaders[CF_PROCCOLS];
    Item *ip;
    int start[CF_PROCCOLS] = { 0 };
    int end[CF_PROCCOLS] = { 0 };
    bool matched = false;

    if (PROCESSTABLE == NULL)
    {
        CfOut(cf_error, "", "!! IsProcessNameRunning: PROCESSTABLE is empty");
        return false;
    }

    GetProcessColumnNames(PROCESSTABLE->name, (char **) colHeaders, start, end);

    for (ip = PROCESSTABLE->next; ip != NULL; ip = ip->next)    // iterate over ps lines
    {
        char *lineSplit[CF_PROCCOLS];

        if (NULL_OR_EMPTY(ip->name))
        {
            continue;
        }

        if (!SplitProcLine(ip->name, colHeaders, start, end, lineSplit))
        {
            CfOut(cf_error, "", "!! IsProcessNameRunning: Could not split process line \"%s\"", ip->name);
            continue;
        }

        if (SelectProcRegexMatch("CMD", "COMMAND", procNameRegex, colHeaders, lineSplit))
        {
            matched = true;
            break;
        }
    }

    return matched;
}
コード例 #7
0
ファイル: processes_select.c プロジェクト: atsaloli/core
int LoadProcessTable()
{
    FILE *prp;
    char pscomm[CF_MAXLINKSIZE];
    Item *rootprocs = NULL;
    Item *otherprocs = NULL;


    if (PROCESSTABLE)
    {
        Log(LOG_LEVEL_VERBOSE, "Reusing cached process table");
        return true;
    }

    LoadPlatformExtraTable();

    CheckPsLineLimitations();

    const char *psopts = GetProcessOptions();

    snprintf(pscomm, CF_MAXLINKSIZE, "%s %s", VPSCOMM[VPSHARDCLASS], psopts);

    Log(LOG_LEVEL_VERBOSE, "Observe process table with %s", pscomm);

    if ((prp = cf_popen(pscomm, "r", false)) == NULL)
    {
        Log(LOG_LEVEL_ERR, "Couldn't open the process list with command '%s'. (popen: %s)", pscomm, GetErrorStr());
        return false;
    }

    size_t vbuff_size = CF_BUFSIZE;
    char *vbuff = xmalloc(vbuff_size);

# ifdef HAVE_GETZONEID

    char *names[CF_PROCCOLS];
    int start[CF_PROCCOLS];
    int end[CF_PROCCOLS];
    Seq *pidlist = SeqNew(1, NULL);
    Seq *rootpidlist = SeqNew(1, NULL);
    bool global_zone = IsGlobalZone();

    if (global_zone)
    {
        int res = ZLoadProcesstable(pidlist, rootpidlist);

        if (res == false)
        {
            Log(LOG_LEVEL_ERR, "Unable to load solaris zone process table.");
            return false;
        }
    }

# endif

    ARG_UNUSED bool header = true;           /* used only if HAVE_GETZONEID */

    for (;;)
    {
        ssize_t res = CfReadLine(&vbuff, &vbuff_size, prp);
        if (res == -1)
        {
            if (!feof(prp))
            {
                Log(LOG_LEVEL_ERR, "Unable to read process list with command '%s'. (fread: %s)", pscomm, GetErrorStr());
                cf_pclose(prp);
                free(vbuff);
                return false;
            }
            else
            {
                break;
            }
        }
        Chop(vbuff, vbuff_size);

# ifdef HAVE_GETZONEID

        if (global_zone)
        {
            if (header)
            {   /* this is the banner so get the column header names for later use*/
                GetProcessColumnNames(vbuff, &names[0], start, end);
            }
            else
            {
               int gpid = ExtractPid(vbuff, names, end);

               if (!IsGlobalProcess(gpid, pidlist, rootpidlist))
               {
                    continue;
               }
            }
        }

# endif
        AppendItem(&PROCESSTABLE, vbuff, "");

        header = false;
    }

    cf_pclose(prp);

/* Now save the data */
    const char* const statedir = GetStateDir();

    snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_procs", statedir, FILE_SEPARATOR);
    RawSaveItemList(PROCESSTABLE, vbuff, NewLineMode_Unix);

# ifdef HAVE_GETZONEID
    if (global_zone) /* pidlist and rootpidlist are empty if we're not in the global zone */
    {
        Item *ip = PROCESSTABLE;
        while (ip != NULL)
        {
            ZCopyProcessList(&rootprocs, ip, rootpidlist, names, end);
            ip = ip->next;
        }
        ReverseItemList(rootprocs);
        ip = PROCESSTABLE;
        while (ip != NULL)
        {
            ZCopyProcessList(&otherprocs, ip, pidlist, names, end);
            ip = ip->next;
        }
        ReverseItemList(otherprocs);
    }
    else
# endif
    {
        CopyList(&rootprocs, PROCESSTABLE);
        CopyList(&otherprocs, PROCESSTABLE);

        while (DeleteItemNotContaining(&rootprocs, "root"))
        {
        }

        while (DeleteItemContaining(&otherprocs, "root"))
        {
        }
    }
    if (otherprocs)
    {
        PrependItem(&rootprocs, otherprocs->name, NULL);
    }

    snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_rootprocs", statedir, FILE_SEPARATOR);
    RawSaveItemList(rootprocs, vbuff, NewLineMode_Unix);
    DeleteItemList(rootprocs);

    snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_otherprocs", statedir, FILE_SEPARATOR);
    RawSaveItemList(otherprocs, vbuff, NewLineMode_Unix);
    DeleteItemList(otherprocs);

    free(vbuff);
    return true;
}
コード例 #8
0
ファイル: processes_select.c プロジェクト: atsaloli/core
static void ReadFromUcbPsPipe(FILE *cmd)
{
    char *names[CF_PROCCOLS];
    memset(names, 0, sizeof(names));
    int start[CF_PROCCOLS];
    int end[CF_PROCCOLS];
    char *line = NULL;
    size_t linesize = 0;
    bool header = true;
    time_t pstime = time(NULL);
    int pidcol = -1;
    int cmdcol = -1;
    while (CfReadLine(&line, &linesize, cmd) > 0)
    {
        if (header)
        {
            GetProcessColumnNames(line, names, start, end);

            for (int i = 0; names[i]; i++)
            {
                if (strcmp(names[i], "PID") == 0)
                {
                    pidcol = i;
                }
                else if (strcmp(names[i], "COMMAND") == 0
                           || strcmp(names[i], "CMD") == 0)
                {
                    cmdcol = i;
                }
            }

            if (pidcol < 0 || cmdcol < 0)
            {
                Log(LOG_LEVEL_ERR,
                    "Could not find PID and/or CMD/COMMAND column in "
                    "ps output: \"%s\"", line);
                break;
            }

            header = false;
            continue;
        }


        char *columns[CF_PROCCOLS];
        memset(columns, 0, sizeof(columns));
        if (!SplitProcLine(line, pstime, names, start, end,
                           UCB_STYLE_PS_COLUMN_ALGORITHM, columns))
        {
            Log(LOG_LEVEL_WARNING,
                "Not able to parse ps output: \"%s\"", line);
        }

        StringMapInsert(UCB_PS_MAP, columns[pidcol], columns[cmdcol]);
        // We avoid strdup'ing these strings by claiming ownership here.
        columns[pidcol] = NULL;
        columns[cmdcol] = NULL;

        for (int i = 0; i < CF_PROCCOLS; i++)
        {
            // There may be some null entries here, but since we "steal"
            // strings in the section above, we may have set some of them to
            // NULL and there may be following non-NULL fields.
            free(columns[i]);
        }
    }

    if (!feof(cmd) && ferror(cmd))
    {
        Log(LOG_LEVEL_ERR, "Error while reading output from ps: %s",
            GetErrorStr());
    }

    for (int i = 0; names[i] && i < CF_PROCCOLS; i++)
    {
        free(names[i]);
    }

    free(line);
}
コード例 #9
0
ファイル: processes_select.c プロジェクト: atsaloli/core
/* Load processes using zone-aware ps
 * to obtain solaris list of global
 * process ids for root and non-root
 * users to lookup later */
int ZLoadProcesstable(Seq *pidlist, Seq *rootpidlist)
{

    char *names[CF_PROCCOLS];
    int start[CF_PROCCOLS];
    int end[CF_PROCCOLS];

    const char *pscmd = "/usr/bin/ps -Aleo zone,user,pid";

    FILE *psf = cf_popen(pscmd, "r", false);
    if (psf == NULL)
    {
        Log(LOG_LEVEL_ERR, "ZLoadProcesstable: Couldn't open the process list with command %s.", pscmd);
        return false;
    }

    size_t pbuff_size = CF_BUFSIZE;
    char *pbuff = xmalloc(pbuff_size);
    bool header = true;

    while (true)
    {
        ssize_t res = CfReadLine(&pbuff, &pbuff_size, psf);
        if (res == -1)
        {
            if (!feof(psf))
            {
                Log(LOG_LEVEL_ERR, "IsGlobalProcess(char **, int): Unable to read process list with command '%s'. (fread: %s)", pscmd, GetErrorStr());
                cf_pclose(psf);
                free(pbuff);
                return false;
            }
            else
            {
                break;
            }
        }
        Chop(pbuff, pbuff_size);
        if (header) /* This line is the header. */
        {
            GetProcessColumnNames(pbuff, &names[0], start, end);
        }
        else
        {
            int pid = ExtractPid(pbuff, &names[0], end);

            size_t zone_offset = strspn(pbuff, " ");
            size_t zone_end_offset = strcspn(pbuff + zone_offset, " ") + zone_offset;
            size_t user_offset = strspn(pbuff + zone_end_offset, " ") + zone_end_offset;
            size_t user_end_offset = strcspn(pbuff + user_offset, " ") + user_offset;
            bool is_global = (zone_end_offset - zone_offset == 6
                                  && strncmp(pbuff + zone_offset, "global", 6) == 0);
            bool is_root = (user_end_offset - user_offset == 4
                                && strncmp(pbuff + user_offset, "root", 4) == 0);

            if (is_global && is_root)
            {
                SeqAppend(rootpidlist, (void*)(intptr_t)pid);
            }
            else if (is_global && !is_root)
            {
                SeqAppend(pidlist, (void*)(intptr_t)pid);
            }
        }

        header = false;
    }
    cf_pclose(psf);
    free(pbuff);
    return true;
}
コード例 #10
0
static int FindPidMatches(Item *procdata, Item **killlist, Attributes a, Promise *pp)
{
    Item *ip;
    int pid = -1, matches = 0, i, s, e, promised_zero;
    pid_t cfengine_pid = getpid();
    char *names[CF_PROCCOLS];   /* ps headers */
    int start[CF_PROCCOLS];
    int end[CF_PROCCOLS];

    if (procdata == NULL)
    {
        return 0;
    }

    GetProcessColumnNames(procdata->name, (char **) names, start, end);

    for (ip = procdata->next; ip != NULL; ip = ip->next)
    {
        CF_OCCUR++;

        if (BlockTextMatch(pp->promiser, ip->name, &s, &e))
        {
            if (NULL_OR_EMPTY(ip->name))
            {
                continue;
            }

            if (!SelectProcess(ip->name, names, start, end, a, pp))
            {
                continue;
            }

            pid = ExtractPid(ip->name, names, start, end);

            if (pid == -1)
            {
                CfOut(cf_verbose, "", "Unable to extract pid while looking for %s\n", pp->promiser);
                continue;
            }

            CfOut(cf_verbose, "", " ->  Found matching pid %d\n     (%s)", pid, ip->name);

            matches++;

            if (pid == 1)
            {
                if ((RlistLen(a.signals) == 1) && IsStringIn(a.signals, "hup"))
                {
                    CfOut(cf_verbose, "", "(Okay to send only HUP to init)\n");
                }
                else
                {
                    continue;
                }
            }

            if (pid < 4 && a.signals)
            {
                CfOut(cf_verbose, "", "Will not signal or restart processes 0,1,2,3 (occurred while looking for %s)\n",
                      pp->promiser);
                continue;
            }

            promised_zero = a.process_count.min_range == 0 && a.process_count.max_range == 0;

            if (a.transaction.action == cfa_warn && promised_zero)
            {
                CfOut(cf_error, "", "Process alert: %s\n", procdata->name);     /* legend */
                CfOut(cf_error, "", "Process alert: %s\n", ip->name);
                continue;
            }

            if (pid == cfengine_pid && a.signals)
            {
                CfOut(cf_verbose, "", " !! cf-agent will not signal itself!\n");
                continue;
            }

            PrependItem(killlist, ip->name, "");
            (*killlist)->counter = pid;
        }
    }

// Free up allocated memory

    for (i = 0; i < CF_PROCCOLS; i++)
    {
        if (names[i] != NULL)
        {
            free(names[i]);
        }
    }

    return matches;
}