Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/zabbix/zabbix.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sysinfo.h7
-rw-r--r--src/libs/zbxsysinfo/linux/proc.c381
-rw-r--r--src/libs/zbxsysinfo/solaris/proc.c273
-rw-r--r--src/zabbix_agent/procstat.c241
4 files changed, 660 insertions, 242 deletions
diff --git a/include/sysinfo.h b/include/sysinfo.h
index 0d805422aac..7175d8a580d 100644
--- a/include/sysinfo.h
+++ b/include/sysinfo.h
@@ -276,4 +276,11 @@ typedef struct
}
MODE_FUNCTION;
+/* the fields used by proc queries */
+#define ZBX_SYSINFO_PROC_NONE 0x0000
+#define ZBX_SYSINFO_PROC_PID 0x0001
+#define ZBX_SYSINFO_PROC_NAME 0x0002
+#define ZBX_SYSINFO_PROC_CMDLINE 0x0004
+#define ZBX_SYSINFO_PROC_USER 0x0008
+
#endif
diff --git a/src/libs/zbxsysinfo/linux/proc.c b/src/libs/zbxsysinfo/linux/proc.c
index 9aced0905ac..82a16c78c23 100644
--- a/src/libs/zbxsysinfo/linux/proc.c
+++ b/src/libs/zbxsysinfo/linux/proc.c
@@ -24,6 +24,40 @@
#include "stats.h"
#include "db.h"
+
+typedef struct
+{
+ pid_t pid;
+ uid_t uid;
+
+ char *name;
+
+ /* the process name taken from the 0th argument */
+ char *name_arg0;
+
+ /* process command line in format <arg0> <arg1> ... <argN>\0 */
+ char *cmdline;
+}
+zbx_sysinfo_proc_t;
+
+
+/******************************************************************************
+ * *
+ * Function: zbx_sysinfo_proc_free *
+ * *
+ * Purpose: frees process data structure *
+ * *
+ ******************************************************************************/
+void zbx_sysinfo_proc_free(zbx_sysinfo_proc_t *proc)
+{
+ zbx_free(proc->name);
+ zbx_free(proc->name_arg0);
+ zbx_free(proc->cmdline);
+
+ zbx_free(proc);
+}
+
+
static int get_cmdline(FILE *f_cmd, char **line, size_t *line_offset)
{
size_t line_alloc = ZBX_KIBIBYTE, n;
@@ -786,7 +820,128 @@ out:
/******************************************************************************
* *
- * Function: procstat_read_value *
+ * Function: proc_get_process_name *
+ * *
+ * Purpose: returns process name *
+ * *
+ * Parameters: pid - [IN] the process identifier *
+ * *
+ * Return value: The process name. *
+ * *
+ * Comments: The returned name must be freed by the caller. *
+ * *
+ ******************************************************************************/
+static char *proc_get_process_name(pid_t pid)
+{
+ char tmp[MAX_STRING_LEN], *ptr, *name = NULL, *pend;
+ int fd, offset = 0, n;
+
+ zbx_snprintf(tmp, sizeof(tmp), "/proc/%d/status", (int)pid);
+
+ if (-1 == (fd = open(tmp, O_RDONLY)))
+ return NULL;
+
+ while (0 < (n = read(fd, tmp + offset, sizeof(tmp) - offset - 1)))
+ {
+ n += offset;
+ tmp[n] = '\0';
+
+ for (ptr = tmp; NULL != ptr; ptr = pend + 1)
+ {
+ if (NULL == (pend = strchr(ptr, '\n')))
+ break;
+
+ if (0 == strncmp(ptr, "Name:\t", 6))
+ {
+ *pend = '\0';
+ name = zbx_strdup(NULL, ptr + 6);
+ goto out;
+ }
+ }
+
+ offset = n - (ptr - tmp);
+ memmove(tmp, ptr, offset);
+ }
+out:
+ close(fd);
+
+ return name;
+}
+
+/******************************************************************************
+ * *
+ * Function: proc_get_process_cmdline *
+ * *
+ * Purpose: returns process command line *
+ * *
+ * Parameters: pid - [IN] the process identifier *
+ * *
+ * Return value: The process command line *
+ * *
+ * Comments: The returned command line must be freed by the caller. *
+ * *
+ ******************************************************************************/
+static char *proc_get_process_cmdline(pid_t pid)
+{
+ char tmp[MAX_STRING_LEN], *cmdline, *arg;
+ int fd, n;
+ size_t cmdline_alloc = ZBX_KIBIBYTE, cmdline_offset = 0;
+
+ zbx_snprintf(tmp, sizeof(tmp), "/proc/%d/cmdline", (int)pid);
+
+ if (-1 == (fd = open(tmp, O_RDONLY)))
+ return NULL;
+
+ cmdline = zbx_malloc(NULL, cmdline_alloc);
+
+ while (0 < (n = read(fd, cmdline + cmdline_offset, cmdline_alloc - cmdline_offset)))
+ {
+ cmdline_offset += n;
+
+ if (cmdline_offset == cmdline_alloc)
+ {
+ cmdline_alloc *= 2;
+ cmdline = realloc(cmdline, cmdline_alloc);
+ }
+ }
+
+ close(fd);
+
+ cmdline[cmdline_offset] = '\0';
+
+ for (arg = cmdline; '\0' != *arg; arg = arg + strlen(arg))
+ *arg++ = ' ';
+
+ return cmdline;
+}
+
+/******************************************************************************
+ * *
+ * Function: proc_get_process_uid *
+ * *
+ * Purpose: returns process user identifer *
+ * *
+ * Parameters: pid - [IN] the process identifier *
+ * *
+ * Return value: The process user identifier *
+ * *
+ ******************************************************************************/
+static uid_t proc_get_process_uid(pid_t pid)
+{
+ char tmp[MAX_STRING_LEN];
+ zbx_stat_t st;
+
+ zbx_snprintf(tmp, sizeof(tmp), "/proc/%d", (int)pid);
+
+ if (0 != zbx_stat(tmp, &st))
+ return 0;
+
+ return st.st_uid;
+}
+
+/******************************************************************************
+ * *
+ * Function: proc_read_value *
* *
* Purpose: read 64 bit unsigned space or zero character terminated integer *
* from a text string *
@@ -797,7 +952,7 @@ out:
* Return value: The length of the parsed text or FAIL if parsing failed. *
* *
******************************************************************************/
-static int procstat_read_value(const char *ptr, zbx_uint64_t *value)
+static int proc_read_value(const char *ptr, zbx_uint64_t *value)
{
const char *start = ptr;
int len;
@@ -861,7 +1016,7 @@ static int proc_read_cpu_util(zbx_procstat_util_t *procutil)
switch (++n)
{
case 12:
- if (FAIL == (offset = procstat_read_value(ptr, &procutil->utime)))
+ if (FAIL == (offset = proc_read_value(ptr, &procutil->utime)))
{
ret = -EINVAL;
goto out;
@@ -870,7 +1025,7 @@ static int proc_read_cpu_util(zbx_procstat_util_t *procutil)
break;
case 13:
- if (FAIL == (offset = procstat_read_value(ptr, &procutil->stime)))
+ if (FAIL == (offset = proc_read_value(ptr, &procutil->stime)))
{
ret = -EINVAL;
goto out;
@@ -879,7 +1034,7 @@ static int proc_read_cpu_util(zbx_procstat_util_t *procutil)
break;
case 20:
- if (FAIL == (offset = procstat_read_value(ptr, &procutil->starttime)))
+ if (FAIL == (offset = proc_read_value(ptr, &procutil->starttime)))
{
ret = -EINVAL;
goto out;
@@ -896,9 +1051,68 @@ out:
return ret;
}
+
+/******************************************************************************
+ * *
+ * Function: proc_match_name *
+ * *
+ * Purpose: checks if the process name matches filter *
+ * *
+ ******************************************************************************/
+static int proc_match_name(const zbx_sysinfo_proc_t *proc, const char *procname)
+{
+ if (NULL == procname)
+ return SUCCEED;
+
+ if (NULL != proc->name && 0 == strcmp(procname, proc->name))
+ return SUCCEED;
+
+ if (NULL != proc->name_arg0 && 0 == strcmp(procname, proc->name_arg0))
+ return SUCCEED;
+
+ return FAIL;
+}
+
+/******************************************************************************
+ * *
+ * Function: proc_match_user *
+ * *
+ * Purpose: checks if the process user matches filter *
+ * *
+ ******************************************************************************/
+
+static int proc_match_user(const zbx_sysinfo_proc_t *proc, const struct passwd *usrinfo)
+{
+ if (NULL == usrinfo)
+ return SUCCEED;
+
+ if (proc->uid == usrinfo->pw_uid)
+ return SUCCEED;
+
+ return FAIL;
+}
+
+/******************************************************************************
+ * *
+ * Function: proc_match_cmdline *
+ * *
+ * Purpose: checks if the process command line matches filter *
+ * *
+ ******************************************************************************/
+static int proc_match_cmdline(const zbx_sysinfo_proc_t *proc, const char *cmdline)
+{
+ if (NULL == cmdline)
+ return SUCCEED;
+
+ if (NULL != zbx_regexp_match(proc->cmdline, cmdline, NULL))
+ return SUCCEED;
+
+ return FAIL;
+}
+
/******************************************************************************
* *
- * Function: zbx_proc_get_stats *
+ * Function: zbx_proc_get_process_stats *
* *
* Purpose: get process cpu utilization data *
* *
@@ -906,9 +1120,9 @@ out:
* procs_num - [IN] the number of items in procs array *
* *
******************************************************************************/
-void zbx_proc_get_stats(zbx_procstat_util_t *procs, int procs_num)
+void zbx_proc_get_process_stats(zbx_procstat_util_t *procs, int procs_num)
{
- const char *__function_name = "zbx_proc_get_pids";
+ const char *__function_name = "zbx_proc_get_process_stats";
int i;
zabbix_log(LOG_LEVEL_TRACE, "In %s() procs_num:%d", __function_name, procs_num);
@@ -921,12 +1135,97 @@ void zbx_proc_get_stats(zbx_procstat_util_t *procs, int procs_num)
/******************************************************************************
* *
- * Function: zbx_proc_get_pids *
+ * Function: zbx_proc_get_processes *
+ * *
+ * Purpose: get system processes *
+ * *
+ * Parameters: processes - [OUT] the system processes *
+ * flags - [IN] the flags specifying the process properties *
+ * that must be returned *
+ * *
+ ******************************************************************************/
+int zbx_proc_get_processes(zbx_vector_ptr_t *processes, unsigned int flags)
+{
+ const char *__function_name = "zbx_proc_get_processes";
+
+ DIR *dir;
+ struct dirent *entries;
+ int ret = FAIL, pid;
+ char *arg0;
+ zbx_sysinfo_proc_t *proc;
+
+
+ zabbix_log(LOG_LEVEL_TRACE, "In %s()", __function_name);
+
+ if (NULL == (dir = opendir("/proc")))
+ {
+ ret = -errno;
+ goto out;
+ }
+
+ while (NULL != (entries = readdir(dir)))
+ {
+ /* skip entries not containing pids */
+ if (FAIL == is_uint32(entries->d_name, &pid))
+ continue;
+
+ proc = (zbx_sysinfo_proc_t *)zbx_malloc(NULL, sizeof(zbx_sysinfo_proc_t));
+ memset(proc, 0, sizeof(zbx_sysinfo_proc_t));
+
+ proc->pid = pid;
+
+ if (0 != (flags & ZBX_SYSINFO_PROC_USER))
+ proc->uid = proc_get_process_uid(pid);
+
+ if (0 != (flags & (ZBX_SYSINFO_PROC_CMDLINE | ZBX_SYSINFO_PROC_NAME)))
+ proc->cmdline = proc_get_process_cmdline(pid);
+
+ if (0 != (flags & ZBX_SYSINFO_PROC_NAME) && NULL != proc->cmdline)
+ {
+ proc->name = proc_get_process_name(pid);
+
+ if (NULL == (arg0 = strrchr(proc->cmdline, '/')))
+ proc->name_arg0 = zbx_strdup(NULL, proc->cmdline);
+ else
+ proc->name_arg0 = zbx_strdup(NULL, arg0 + 1);
+ }
+
+ zbx_vector_ptr_append(processes, proc);
+ }
+
+ closedir(dir);
+
+ ret = SUCCEED;
+out:
+ zabbix_log(LOG_LEVEL_TRACE, "End of %s(): %s, processes:%d", __function_name, zbx_result_string(ret),
+ processes->values_num);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Function: zbx_proc_free_processes *
+ * *
+ * Purpose: frees process vector read by zbx_proc_get_processes function *
+ * *
+ * Parameters: processes - [IN/OUT] the process vector to free *
+ * *
+ ******************************************************************************/
+void zbx_proc_free_processes(zbx_vector_ptr_t *processes)
+{
+ zbx_vector_ptr_clear_ext(processes, (zbx_mem_free_func_t)zbx_sysinfo_proc_free);
+}
+
+/******************************************************************************
+ * *
+ * Function: zbx_proc_get_matching_pids *
* *
* Purpose: get pids matching the specified process name, user name and *
* command line *
* *
- * Parameters: procname - [IN] the process name, NULL - all *
+ * Parameters: processes - [IN] the list of system processes *
+ * procname - [IN] the process name, NULL - all *
* username - [IN] the user name, NULL - all *
* cmdline - [IN] the command line, NULL - all *
* pids - [OUT] the vector of matching pids *
@@ -935,16 +1234,13 @@ void zbx_proc_get_stats(zbx_procstat_util_t *procs, int procs_num)
* -errno - failed to read pids *
* *
******************************************************************************/
-int zbx_proc_get_pids(const char *procname, const char *username, const char *cmdline, zbx_uint64_t flags,
- zbx_vector_uint64_t *pids)
+void zbx_proc_get_matching_pids(const zbx_vector_ptr_t *processes, const char *procname, const char *username,
+ const char *cmdline, zbx_uint64_t flags, zbx_vector_uint64_t *pids)
{
- const char *__function_name = "zbx_proc_get_pids";
- DIR *dir;
- struct dirent *entries;
- struct passwd *usrinfo;
- char tmp[MAX_STRING_LEN];
- FILE *f_cmd = NULL, *f_stat = NULL;
- int pid, ret = FAIL;
+ const char *__function_name = "zbx_proc_get_matching_pids";
+ struct passwd *usrinfo;
+ int i;
+ zbx_sysinfo_proc_t *proc;
zabbix_log(LOG_LEVEL_TRACE, "In %s() procname:%s username:%s cmdline:%s", __function_name,
ZBX_NULL2EMPTY_STR(procname), ZBX_NULL2EMPTY_STR(username), ZBX_NULL2EMPTY_STR(cmdline));
@@ -953,61 +1249,28 @@ int zbx_proc_get_pids(const char *procname, const char *username, const char *cm
{
/* in the case of invalid user there are no matching processes, set empty result */
if (NULL == (usrinfo = getpwnam(username)))
- {
- ret = SUCCEED;
goto out;
- }
}
else
usrinfo = NULL;
- if (NULL == (dir = opendir("/proc")))
- {
- ret = -errno;
- goto out;
- }
-
- while (NULL != (entries = readdir(dir)))
+ for (i = 0; i < processes->values_num; i++)
{
- /* skip entries not containing pids */
- if (FAIL == is_uint32(entries->d_name, &pid))
- continue;
-
- zbx_fclose(f_cmd);
- zbx_fclose(f_stat);
-
- zbx_snprintf(tmp, sizeof(tmp), "/proc/%s/cmdline", entries->d_name);
-
- if (NULL == (f_cmd = fopen(tmp, "r")))
- continue;
-
- zbx_snprintf(tmp, sizeof(tmp), "/proc/%s/status", entries->d_name);
-
- if (NULL == (f_stat = fopen(tmp, "r")))
- continue;
+ proc = (zbx_sysinfo_proc_t *)processes->values[i];
- if (FAIL == check_procname(f_cmd, f_stat, procname))
+ if (SUCCEED != proc_match_user(proc, usrinfo))
continue;
- if (FAIL == check_proccomm(f_cmd, cmdline))
+ if (SUCCEED != proc_match_name(proc, procname))
continue;
- if (FAIL == check_user(f_stat, usrinfo))
+ if (SUCCEED != proc_match_cmdline(proc, cmdline))
continue;
- zbx_vector_uint64_append(pids, (zbx_uint64_t)pid);
+ zbx_vector_uint64_append(pids, (zbx_uint64_t)proc->pid);
}
-
- zbx_fclose(f_cmd);
- zbx_fclose(f_stat);
-
- closedir(dir);
-
- ret = SUCCEED;
out:
- zabbix_log(LOG_LEVEL_TRACE, "End of %s(): %s", __function_name, zbx_result_string(ret));
-
- return ret;
+ zabbix_log(LOG_LEVEL_TRACE, "End of %s()", __function_name);
}
int PROC_CPU_UTIL(AGENT_REQUEST *request, AGENT_RESULT *result)
diff --git a/src/libs/zbxsysinfo/solaris/proc.c b/src/libs/zbxsysinfo/solaris/proc.c
index 8e1f6fdba33..ec36403922e 100644
--- a/src/libs/zbxsysinfo/solaris/proc.c
+++ b/src/libs/zbxsysinfo/solaris/proc.c
@@ -24,6 +24,39 @@
#include "log.h"
#include "stats.h"
+typedef struct
+{
+ pid_t pid;
+ uid_t uid;
+
+ char *name;
+
+ /* process command line in format <arg0> <arg1> ... <argN>\0 */
+ char *cmdline;
+
+#ifdef HAVE_ZONE_H
+ zoneid_t zoneid;
+#endif
+}
+zbx_sysinfo_proc_t;
+
+
+/******************************************************************************
+ * *
+ * Function: zbx_sysinfo_proc_free *
+ * *
+ * Purpose: frees process data structure *
+ * *
+ ******************************************************************************/
+void zbx_sysinfo_proc_free(zbx_sysinfo_proc_t *proc)
+{
+ zbx_free(proc->name);
+ zbx_free(proc->cmdline);
+
+ zbx_free(proc);
+}
+
+
static int check_procstate(psinfo_t *psinfo, int zbx_proc_stat)
{
if (zbx_proc_stat == ZBX_PROC_STAT_ALL)
@@ -322,6 +355,82 @@ out:
/******************************************************************************
* *
+ * Function: proc_match_name *
+ * *
+ * Purpose: checks if the process name matches filter *
+ * *
+ ******************************************************************************/
+static int proc_match_name(const zbx_sysinfo_proc_t *proc, const char *procname)
+{
+ if (NULL == procname)
+ return SUCCEED;
+
+ if (NULL != proc->name && 0 == strcmp(procname, proc->name))
+ return SUCCEED;
+
+ return FAIL;
+}
+
+/******************************************************************************
+ * *
+ * Function: proc_match_user *
+ * *
+ * Purpose: checks if the process user matches filter *
+ * *
+ ******************************************************************************/
+
+static int proc_match_user(const zbx_sysinfo_proc_t *proc, const struct passwd *usrinfo)
+{
+ if (NULL == usrinfo)
+ return SUCCEED;
+
+ if (proc->uid == usrinfo->pw_uid)
+ return SUCCEED;
+
+ return FAIL;
+}
+
+/******************************************************************************
+ * *
+ * Function: proc_match_cmdline *
+ * *
+ * Purpose: checks if the process command line matches filter *
+ * *
+ ******************************************************************************/
+static int proc_match_cmdline(const zbx_sysinfo_proc_t *proc, const char *cmdline)
+{
+ if (NULL == cmdline)
+ return SUCCEED;
+
+ if (NULL != zbx_regexp_match(proc->cmdline, cmdline, NULL))
+ return SUCCEED;
+
+ return FAIL;
+}
+
+
+#ifdef HAVE_ZONE_H
+/******************************************************************************
+ * *
+ * Function: proc_match_user *
+ * *
+ * Purpose: checks if the process user matches filter *
+ * *
+ ******************************************************************************/
+static int proc_match_zone(const zbx_sysinfo_proc_t *proc, zbx_uint64_t flags, zoneid_t zoneid)
+{
+ if (0 != (ZBX_PROCSTAT_FLAGS_ZONE_ALL & flags))
+ return SUCCEED;
+
+ if (proc->zoneid == zoneid)
+ return SUCCEED;
+
+ return FAIL;
+}
+#endif
+
+/******************************************************************************
+ * *
* Function: proc_read_cpu_util *
* *
* Purpose: reads process cpu utilization values from /proc/[pid]/stat file *
@@ -376,7 +485,7 @@ static int proc_read_cpu_util(zbx_procstat_util_t *procutil)
/******************************************************************************
* *
- * Function: zbx_proc_get_stats *
+ * Function: zbx_proc_get_process_stats *
* *
* Purpose: get process cpu utilization data *
* *
@@ -384,7 +493,7 @@ static int proc_read_cpu_util(zbx_procstat_util_t *procutil)
* procs_num - [IN] the number of items in procs array *
* *
******************************************************************************/
-void zbx_proc_get_stats(zbx_procstat_util_t *procs, int procs_num)
+void zbx_proc_get_process_stats(zbx_procstat_util_t *procs, int procs_num)
{
const char *__function_name = "zbx_proc_get_stats";
int i;
@@ -399,6 +508,98 @@ void zbx_proc_get_stats(zbx_procstat_util_t *procs, int procs_num)
/******************************************************************************
* *
+ * Function: zbx_proc_get_processes *
+ * *
+ * Purpose: get system processes *
+ * *
+ * Parameters: processes - [OUT] the system processes *
+ * flags - [IN] the flags specifying the process properties *
+ * that must be returned *
+ * *
+ ******************************************************************************/
+int zbx_proc_get_processes(zbx_vector_ptr_t *processes, unsigned int flags)
+{
+ const char *__function_name = "zbx_proc_get_processes";
+
+ DIR *dir;
+ struct dirent *entries;
+ struct passwd *usrinfo;
+ char tmp[MAX_STRING_LEN];
+ int pid, ret = FAIL, fd = -1, n;
+ psinfo_t psinfo; /* In the correct procfs.h, the structure name is psinfo_t */
+ zbx_sysinfo_proc_t *proc;
+
+ zabbix_log(LOG_LEVEL_TRACE, "In %s()", __function_name);
+
+ if (NULL == (dir = opendir("/proc")))
+ {
+ ret = -errno;
+ goto out;
+ }
+
+ while (NULL != (entries = readdir(dir)))
+ {
+ /* skip entries not containing pids */
+ if (FAIL == is_uint32(entries->d_name, &pid))
+ continue;
+
+ zbx_snprintf(tmp, sizeof(tmp), "/proc/%s/psinfo", entries->d_name);
+
+ if (-1 == (fd = open(tmp, O_RDONLY)))
+ continue;
+
+ n = read(fd, &psinfo, sizeof(psinfo));
+ close(fd);
+
+ if (-1 == n)
+ continue;
+
+ proc = (zbx_sysinfo_proc_t *)zbx_malloc(NULL, sizeof(zbx_sysinfo_proc_t));
+ memset(proc, 0, sizeof(zbx_sysinfo_proc_t));
+
+ proc->pid = pid;
+
+ if (0 != (flags & ZBX_SYSINFO_PROC_NAME))
+ proc->name = zbx_strdup(NULL, psinfo.pr_fname);
+
+ if (0 != (flags & ZBX_SYSINFO_PROC_USER))
+ proc->uid = psinfo.pr_uid;
+
+ if (0 != (flags & ZBX_SYSINFO_PROC_CMDLINE))
+ proc->cmdline = zbx_strdup(NULL, psinfo.pr_psargs);
+
+#ifdef HAVE_ZONE_H
+ proc->zoneid = psinfo.pr_zoneid;
+#endif
+
+ zbx_vector_ptr_append(processes, proc);
+ }
+
+ closedir(dir);
+
+ ret = SUCCEED;
+out:
+ zabbix_log(LOG_LEVEL_TRACE, "End of %s(): %s", __function_name, zbx_result_string(ret));
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Function: zbx_proc_free_processes *
+ * *
+ * Purpose: frees process vector read by zbx_proc_get_processes function *
+ * *
+ * Parameters: processes - [IN/OUT] the process vector to free *
+ * *
+ ******************************************************************************/
+void zbx_proc_free_processes(zbx_vector_ptr_t *processes)
+{
+ zbx_vector_ptr_clear_ext(processes, (zbx_mem_free_func_t)zbx_sysinfo_proc_free);
+}
+
+/******************************************************************************
+ * *
* Function: zbx_proc_get_pids *
* *
* Purpose: get pids matching the specified process name, user name and *
@@ -413,18 +614,19 @@ void zbx_proc_get_stats(zbx_procstat_util_t *procs, int procs_num)
* -errno - failed to read pids *
* *
******************************************************************************/
-int zbx_proc_get_pids(const char *procname, const char *username, const char *cmdline, zbx_uint64_t flags,
- zbx_vector_uint64_t *pids)
+int zbx_proc_get_matching_pids(const zbx_vector_ptr_t *processes, const char *procname, const char *username,
+ const char *cmdline, zbx_uint64_t flags, zbx_vector_uint64_t *pids)
{
- const char *__function_name = "zbx_proc_get_pids";
- DIR *dir;
- struct dirent *entries;
- struct passwd *usrinfo;
- char tmp[MAX_STRING_LEN];
- int pid, ret = FAIL, fd = -1;
- psinfo_t psinfo; /* In the correct procfs.h, the structure name is psinfo_t */
+ const char *__function_name = "zbx_proc_get_matching_pids";
+ DIR *dir;
+ struct dirent *entries;
+ struct passwd *usrinfo;
+ char tmp[MAX_STRING_LEN];
+ int pid, ret = FAIL, fd = -1, i;
+ psinfo_t psinfo; /* In the correct procfs.h, the structure name is psinfo_t */
+ zbx_sysinfo_proc_t *proc;
#ifdef HAVE_ZONE_H
- zoneid_t zoneid;
+ zoneid_t zoneid;
#endif
zabbix_log(LOG_LEVEL_TRACE, "In %s() procname:%s username:%s cmdline:%s zone:%d", __function_name,
@@ -442,64 +644,35 @@ int zbx_proc_get_pids(const char *procname, const char *username, const char *cm
else
usrinfo = NULL;
- if (NULL == (dir = opendir("/proc")))
- {
- ret = -errno;
- goto out;
- }
-
#ifdef HAVE_ZONE_H
zoneid = getzoneid();
#endif
- while (NULL != (entries = readdir(dir)))
+ for (i = 0; i < processes->values_num; i++)
{
- /* skip entries not containing pids */
- if (FAIL == is_uint32(entries->d_name, &pid))
- continue;
-
- if (-1 != fd)
- {
- close(fd);
- fd = -1;
- }
-
- zbx_snprintf(tmp, sizeof(tmp), "/proc/%s/psinfo", entries->d_name);
+ proc = (zbx_sysinfo_proc_t *)processes->values[i];
- if (-1 == (fd = open(tmp, O_RDONLY)))
+ if (SUCCEED != proc_match_user(proc, usrinfo))
continue;
- if (-1 == read(fd, &psinfo, sizeof(psinfo)))
- continue;
-
- if (NULL != procname && '\0' != *procname && 0 != strcmp(procname, psinfo.pr_fname))
- continue;
-
- if (NULL != usrinfo && usrinfo->pw_uid != psinfo.pr_uid)
+ if (SUCCEED != proc_match_name(proc, procname))
continue;
- if (NULL != cmdline && '\0' != *cmdline && NULL == zbx_regexp_match(psinfo.pr_psargs, cmdline, NULL))
+ if (SUCCEED != proc_match_cmdline(proc, cmdline))
continue;
#ifdef HAVE_ZONE_H
- if (0 == (ZBX_PROCSTAT_FLAGS_ZONE_ALL & flags) && psinfo.pr_zoneid != zoneid)
+ if (SUCCEED != proc_match_zone(proc, flags, zoneid))
continue;
#endif
- zbx_vector_uint64_append(pids, (zbx_uint64_t)pid);
+ zbx_vector_uint64_append(pids, (zbx_uint64_t)proc->pid);
}
-
- closedir(dir);
- if (-1 != fd)
- close(fd);
-
- ret = SUCCEED;
out:
- zabbix_log(LOG_LEVEL_TRACE, "End of %s(): %s", __function_name, zbx_result_string(ret));
-
- return ret;
+ zabbix_log(LOG_LEVEL_TRACE, "End of %s()", __function_name);
}
+
int PROC_CPU_UTIL(AGENT_REQUEST *request, AGENT_RESULT *result)
{
const char *procname, *username, *cmdline, *tmp, *flags;
diff --git a/src/zabbix_agent/procstat.c b/src/zabbix_agent/procstat.c
index 05626cc2169..b7cb3190f54 100644
--- a/src/zabbix_agent/procstat.c
+++ b/src/zabbix_agent/procstat.c
@@ -83,9 +83,6 @@ static zbx_dshm_ref_t procstat_ref;
typedef struct
{
- /* the number of processes in process statistics snapshot */
- int pids_num;
-
/* a linked list of active queries (offset of the first active query) */
int queries;
@@ -112,10 +109,6 @@ zbx_procstat_header_t;
#define PROCSTAT_QUERY_NEXT(base, query) \
(zbx_procstat_query_t*)PROCSTAT_PTR_NULL(base, query->next)
-#define PROCSTAT_SNAPSHOT(base) \
- ((zbx_procstat_util_t *)((char *)base + ((zbx_procstat_header_t *)base)->size - \
- ((zbx_procstat_header_t *)base)->pids_num * sizeof(zbx_procstat_util_t)))
-
#define PROCSTAT_OFFSET(base, ptr) ((char *)ptr - (char *)base)
/* data sample collected every second for the process cpu utilization queries */
@@ -181,10 +174,19 @@ typedef struct
}
zbx_procstat_query_data_t;
+
+static zbx_procstat_util_t *procstat_snapshot;
+static int procstat_snapshot_num;
+
/* external functions used by procstat collector */
-int zbx_proc_get_pids(const char *procname, const char *username, const char *cmdline, zbx_uint64_t flags,
- zbx_vector_uint64_t *pids);
-void zbx_proc_get_stats(zbx_procstat_util_t *procs, int procs_num);
+int zbx_proc_get_processes(zbx_vector_ptr_t *processes, unsigned int flags);
+
+int zbx_proc_get_matching_pids(const zbx_vector_ptr_t *processes, const char *procname, const char *username,
+ const char *cmdline, zbx_uint64_t flags, zbx_vector_uint64_t *pids);
+
+void zbx_proc_get_process_stats(zbx_procstat_util_t *procs, int procs_num);
+
+void zbx_proc_free_processes(zbx_vector_ptr_t *processes);
/******************************************************************************
* *
@@ -204,7 +206,7 @@ static int procstat_dshm_has_enough_space(void *base, size_t size)
{
zbx_procstat_header_t *header = (zbx_procstat_header_t *)base;
- if (header->size > size + header->size_allocated + header->pids_num * sizeof(zbx_procstat_util_t))
+ if (header->size >= size + header->size_allocated)
return SUCCEED;
return FAIL;
@@ -313,8 +315,7 @@ static void procstat_copy_data(void *dst, size_t size_dst, const void *src)
{
const char *__function_name = "procstat_copy_data";
- int offset, size_snapshot, *query_offset, now;
- zbx_procstat_header_t *hsrc = (zbx_procstat_header_t *)src;
+ int offset, *query_offset;
zbx_procstat_header_t *hdst = (zbx_procstat_header_t *)dst;
zbx_procstat_query_t *qsrc, *qdst = NULL;
@@ -324,8 +325,6 @@ static void procstat_copy_data(void *dst, size_t size_dst, const void *src)
hdst->size_allocated = PROCSTAT_ALIGNED_HEADER_SIZE;
hdst->queries = PROCSTAT_NULL_OFFSET;
- now = time(NULL);
-
if (NULL != src)
{
query_offset = &hdst->queries;
@@ -333,10 +332,6 @@ static void procstat_copy_data(void *dst, size_t size_dst, const void *src)
/* copy queries */
for (qsrc = PROCSTAT_QUERY_FIRST(src); NULL != qsrc; qsrc = PROCSTAT_QUERY_NEXT(src, qsrc))
{
- /* don't copy queries not used during the last day */
- if (SEC_PER_DAY < now - qsrc->last_accessed)
- continue;
-
/* the new shared memory segment must have enough space */
offset = procstat_alloc(dst, sizeof(zbx_procstat_query_t));
@@ -351,15 +346,7 @@ static void procstat_copy_data(void *dst, size_t size_dst, const void *src)
*query_offset = offset;
query_offset = &qdst->next;
}
-
- /* copy process cpu utilization snapshot */
- hdst->pids_num = hsrc->pids_num;
- size_snapshot = hsrc->pids_num * sizeof(zbx_procstat_util_t);
- memcpy((char *)dst + hdst->size - size_snapshot, (char *)src + hsrc->size - size_snapshot,
- size_snapshot);
}
- else
- hdst->pids_num = 0;
zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
@@ -461,17 +448,13 @@ static void procstat_add(const char *procname, const char *username, const char
if (NULL != cmdline)
size += ZBX_SIZE_T_ALIGN8(strlen(cmdline) + 1);
- /* reserve space for process cpu utilization snapshot */
- size += sizeof(zbx_procstat_util_t) * 32;
-
/* procstat_add() is called when the shared memory reference has already been validated - */
/* no need to call procstat_reattach() */
- header = (zbx_procstat_header_t *)procstat_ref.addr;
/* reserve space for a new query only if there are no freed queries */
size += ZBX_SIZE_T_ALIGN8(sizeof(zbx_procstat_query_t));
- if (NULL == header || FAIL == procstat_dshm_has_enough_space(header, size))
+ if (NULL == procstat_ref.addr || FAIL == procstat_dshm_has_enough_space(procstat_ref.addr, size))
{
if (FAIL == zbx_dshm_reserve(&collector->procstat, size, &errmsg))
{
@@ -484,9 +467,10 @@ static void procstat_add(const char *procname, const char *username, const char
/* header initialised in procstat_copy_data() which is called back from zbx_dshm_reserve() */
procstat_reattach();
- header = (zbx_procstat_header_t *)procstat_ref.addr;
}
+ header = (zbx_procstat_header_t *)procstat_ref.addr;
+
query_offset = procstat_alloc(procstat_ref.addr, sizeof(zbx_procstat_query_t));
/* initialize the created query */
@@ -530,9 +514,8 @@ static void procstat_free_query_data(zbx_procstat_query_data_t *data)
* runid - [IN] marker for queries to be processed in the *
* current collector iteration *
* *
- * Return value: SUCCEED - unused queries removed, the rest of the queries *
- * copied from shared memory segment to local vector *
- * FAIL - no active quueries *
+ * Return value: The flags defining the process properties to be retrieved. *
+ * See ZBX_SYSINFO_PROC_ defines. *
* *
* Comments: updates queries (runid) in shared memory segment *
* *
@@ -543,7 +526,7 @@ static int procstat_build_local_query_vector(zbx_vector_ptr_t *queries_ptr, int
time_t now;
zbx_procstat_query_t *query;
zbx_procstat_query_data_t *qdata;
- int ret = FAIL;
+ int flags = ZBX_SYSINFO_PROC_NONE, *pnext_query;
zbx_dshm_lock(&collector->procstat);
@@ -554,27 +537,39 @@ static int procstat_build_local_query_vector(zbx_vector_ptr_t *queries_ptr, int
if (PROCSTAT_NULL_OFFSET == header->queries)
goto out;
+ flags = ZBX_SYSINFO_PROC_PID;
+
now = time(NULL);
- zbx_vector_ptr_create(queries_ptr);
+ pnext_query = &header->queries;
for (query = PROCSTAT_QUERY_FIRST(procstat_ref.addr); NULL != query;
query = PROCSTAT_QUERY_NEXT(procstat_ref.addr, query))
{
- /* skip unused queries */
+ /* remove unused queries, the data is still allocated until the next resize */
if (SEC_PER_DAY < now - query->last_accessed)
+ {
+ *pnext_query = query->next;
continue;
+ }
qdata = (zbx_procstat_query_data_t *)zbx_malloc(NULL, sizeof(zbx_procstat_query_data_t));
zbx_vector_uint64_create(&qdata->pids);
/* store the reference to query attributes, which is guaranteed to be */
/* valid until we call process_reattach() */
- qdata->procname = PROCSTAT_PTR_NULL(procstat_ref.addr, query->procname);
- qdata->username = PROCSTAT_PTR_NULL(procstat_ref.addr, query->username);
- qdata->cmdline = PROCSTAT_PTR_NULL(procstat_ref.addr, query->cmdline);
+ if (NULL != (qdata->procname = PROCSTAT_PTR_NULL(procstat_ref.addr, query->procname)))
+ flags |= ZBX_SYSINFO_PROC_NAME;
+
+ if (NULL != (qdata->username = PROCSTAT_PTR_NULL(procstat_ref.addr, query->username)))
+ flags |= ZBX_SYSINFO_PROC_USER;
+
+ if (NULL != (qdata->cmdline = PROCSTAT_PTR_NULL(procstat_ref.addr, query->cmdline)))
+ flags |= ZBX_SYSINFO_PROC_CMDLINE;
+
qdata->flags = query->flags;
qdata->utime = 0;
qdata->stime = 0;
+ qdata->error = 0;
zbx_vector_ptr_append(queries_ptr, qdata);
@@ -585,18 +580,19 @@ static int procstat_build_local_query_vector(zbx_vector_ptr_t *queries_ptr, int
/* is incremented at the end of every data gathering cycle. We can be sure that */
/* our local copy will match the queries in shared memory having the same runid. */
query->runid = runid;
- }
- ret = SUCCEED;
+ pnext_query = &query->next;
+ }
out:
zbx_dshm_unlock(&collector->procstat);
- return ret;
+
+ return flags;
}
/******************************************************************************
* *
- * Function: procstat_get_pids_matching_query_attributes *
+ * Function: procstat_scan_query_pids *
* *
* Purpose: for every query gets the pids of processes matching query *
* attributes *
@@ -606,21 +602,20 @@ out:
* Return value: total number of pids saved in all queries *
* *
******************************************************************************/
-static int procstat_get_pids_matching_query_attributes(zbx_vector_ptr_t queries)
+static int procstat_scan_query_pids(zbx_vector_ptr_t *queries, const zbx_vector_ptr_t *processes)
{
zbx_procstat_query_data_t *qdata;
int i;
int pids_num = 0;
- for (i = 0; i < queries.values_num; i++)
+ for (i = 0; i < queries->values_num; i++)
{
- qdata = (zbx_procstat_query_data_t *)queries.values[i];
+ qdata = (zbx_procstat_query_data_t *)queries->values[i];
- qdata->error = zbx_proc_get_pids(qdata->procname, qdata->username, qdata->cmdline, qdata->flags,
+ zbx_proc_get_matching_pids(processes, qdata->procname, qdata->username, qdata->cmdline, qdata->flags,
&qdata->pids);
- if (SUCCEED == qdata->error)
- pids_num += qdata->pids.values_num;
+ pids_num += qdata->pids.values_num;
}
return pids_num;
@@ -628,39 +623,34 @@ static int procstat_get_pids_matching_query_attributes(zbx_vector_ptr_t queries)
/******************************************************************************
* *
- * Function: procstat_build_unique_pids *
+ * Function: procstat_get_monitored_pids *
* *
* Purpose: creates a list of unique pids that are monitored by current data *
* gathering cycle *
* *
- * Parameters: pids_ptr - [OUT] the list of unique pids *
- * queries - [IN] local, working copy of queries *
- * pids_num - [IN] total number of pids saved in all queries *
+ * Parameters: pids - [OUT] a sorted vector of unique pids *
+ * queries - [IN] local, working copy of queries *
* *
******************************************************************************/
-static void procstat_build_unique_pids(zbx_vector_uint64_t *pids_ptr,
- zbx_vector_ptr_t queries, int pids_num)
+static void procstat_get_monitored_pids(zbx_vector_uint64_t *pids, const zbx_vector_ptr_t *queries)
{
zbx_procstat_query_data_t *qdata;
int i;
- zbx_vector_uint64_create(pids_ptr);
- zbx_vector_uint64_reserve(pids_ptr, pids_num);
-
- for (i = 0; i < queries.values_num; i++)
+ for (i = 0; i < queries->values_num; i++)
{
- qdata = (zbx_procstat_query_data_t *)queries.values[i];
+ qdata = (zbx_procstat_query_data_t *)queries->values[i];
if (SUCCEED != qdata->error)
continue;
- memcpy(pids_ptr->values + pids_ptr->values_num, qdata->pids.values,
+ memcpy(pids->values + pids->values_num, qdata->pids.values,
sizeof(zbx_uint64_t) * qdata->pids.values_num);
- pids_ptr->values_num += qdata->pids.values_num;
+ pids->values_num += qdata->pids.values_num;
}
- zbx_vector_uint64_sort(pids_ptr, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
- zbx_vector_uint64_uniq(pids_ptr, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+ zbx_vector_uint64_sort(pids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+ zbx_vector_uint64_uniq(pids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
}
/******************************************************************************
@@ -669,27 +659,24 @@ static void procstat_build_unique_pids(zbx_vector_uint64_t *pids_ptr,
* *
* Purpose: gets cpu utilization data snapshot for the monitored processes *
* *
- * Parameters: stats_ptr - [OUT] current reading of the per-pid cpu usage *
+ * Parameters: stats - [OUT] current reading of the per-pid cpu usage *
* statistics (array, items correspond to pids) *
- * pids - [IN] pids (unique) for which to collect data in *
- * this iteration *
+ * pids - [IN] pids (unique) for which to collect data in this *
+ * iteration *
* *
* Return value: timestamp of the snapshot *
* *
******************************************************************************/
-static zbx_timespec_t procstat_get_cpu_util_snapshot_for_pids(zbx_procstat_util_t **stats_ptr,
- zbx_vector_uint64_t pids)
+static zbx_timespec_t procstat_get_cpu_util_snapshot_for_pids(zbx_procstat_util_t *stats,
+ zbx_vector_uint64_t *pids)
{
zbx_timespec_t snapshot_timestamp;
int i;
- *stats_ptr = (zbx_procstat_util_t *)zbx_malloc(NULL, sizeof(zbx_procstat_util_t) * pids.values_num);
- memset(*stats_ptr, 0, sizeof(zbx_procstat_util_t) * pids.values_num);
-
- for (i = 0; i < pids.values_num; i++)
- (*stats_ptr)[i].pid = pids.values[i];
+ for (i = 0; i < pids->values_num; i++)
+ stats[i].pid = pids->values[i];
- zbx_proc_get_stats(*stats_ptr, pids.values_num);
+ zbx_proc_get_process_stats(stats, pids->values_num);
zbx_timespec(&snapshot_timestamp);
@@ -711,19 +698,16 @@ static zbx_timespec_t procstat_get_cpu_util_snapshot_for_pids(zbx_procstat_util_
* statistics (array, items correspond to pids) *
* *
******************************************************************************/
-static void procstat_calculate_cpu_util_for_queries(zbx_vector_ptr_t queries,
- zbx_vector_uint64_t pids, const zbx_procstat_util_t *stats)
+static void procstat_calculate_cpu_util_for_queries(zbx_vector_ptr_t *queries,
+ zbx_vector_uint64_t *pids, const zbx_procstat_util_t *stats)
{
zbx_procstat_query_data_t *qdata;
zbx_procstat_util_t *putil;
int j, i;
- for (j = 0; j < queries.values_num; j++)
+ for (j = 0; j < queries->values_num; j++)
{
- qdata = (zbx_procstat_query_data_t *)queries.values[j];
-
- if (SUCCEED != qdata->error)
- continue;
+ qdata = (zbx_procstat_query_data_t *)queries->values[j];
/* sum the cpu utilization for processes that are present in current */
/* and last process cpu utilization snapshot */
@@ -732,14 +716,11 @@ static void procstat_calculate_cpu_util_for_queries(zbx_vector_ptr_t queries,
zbx_uint64_t starttime, utime, stime;
/* find the process utilization data in current snapshot */
- putil = (zbx_procstat_util_t *)bsearch(&qdata->pids.values[i], stats, pids.values_num,
+ putil = (zbx_procstat_util_t *)bsearch(&qdata->pids.values[i], stats, pids->values_num,
sizeof(zbx_procstat_util_t), ZBX_DEFAULT_INT_COMPARE_FUNC);
- if (SUCCEED == qdata->error && SUCCEED != putil->error)
- {
- qdata->error = putil->error;
- break;
- }
+ if (SUCCEED != putil->error)
+ continue;
utime = putil->utime;
stime = putil->stime;
@@ -748,7 +729,7 @@ static void procstat_calculate_cpu_util_for_queries(zbx_vector_ptr_t queries,
/* find the process utilization data in last snapshot */
putil = (zbx_procstat_util_t *)bsearch(&qdata->pids.values[i],
- PROCSTAT_SNAPSHOT(procstat_ref.addr), pids.values_num,
+ procstat_snapshot, procstat_snapshot_num,
sizeof(zbx_procstat_util_t), ZBX_DEFAULT_INT_COMPARE_FUNC);
if (NULL == putil || putil->starttime != starttime)
@@ -769,10 +750,6 @@ static void procstat_calculate_cpu_util_for_queries(zbx_vector_ptr_t queries,
* *
* Parameters: queries - [IN] local, working copy of queries (utime, stime *
* and error must be set) *
- * pids - [IN] pids (unique) for which data is collected in *
- * this iteration *
- * stats - [IN] current reading of the per-pid cpu usage *
- * statistics (array, items correspond to pids) *
* runid - [IN] marker for queries to be processed in the *
* current collector iteration *
* snapshot_timestamp - [IN] timestamp of the current snapshot *
@@ -782,37 +759,17 @@ static void procstat_calculate_cpu_util_for_queries(zbx_vector_ptr_t queries,
* memory segment *
* *
******************************************************************************/
-static void procstat_save_cpu_util_snapshot_in_queries(zbx_vector_ptr_t queries,
- zbx_vector_uint64_t pids, zbx_procstat_util_t *stats,
- int runid, zbx_timespec_t snapshot_timestamp)
+static void procstat_save_cpu_util_snapshot_in_queries(zbx_vector_ptr_t *queries, int runid,
+ zbx_timespec_t snapshot_timestamp)
{
- zbx_procstat_header_t *header;
zbx_procstat_query_t *query;
zbx_procstat_query_data_t *qdata;
int index;
int i;
- char *errmsg = NULL;
zbx_dshm_lock(&collector->procstat);
procstat_reattach();
- header = (zbx_procstat_header_t *)procstat_ref.addr;
-
- if (header->size - header->size_allocated < pids.values_num * sizeof(zbx_procstat_util_t))
- {
- if (FAIL == zbx_dshm_reserve(&collector->procstat, pids.values_num * sizeof(zbx_procstat_util_t) * 1.5,
- &errmsg))
- {
- zabbix_log(LOG_LEVEL_CRIT, "cannot reserve memory in process data collector: %s", errmsg);
- zbx_free(errmsg);
- zbx_dshm_unlock(&collector->procstat);
-
- exit(EXIT_FAILURE);
- }
-
- procstat_reattach();
- header = (zbx_procstat_header_t *)procstat_ref.addr;
- }
for (query = PROCSTAT_QUERY_FIRST(procstat_ref.addr), i = 0; NULL != query;
query = PROCSTAT_QUERY_NEXT(procstat_ref.addr, query))
@@ -820,13 +777,13 @@ static void procstat_save_cpu_util_snapshot_in_queries(zbx_vector_ptr_t queries,
if (runid != query->runid)
continue;
- if (i >= queries.values_num)
+ if (i >= queries->values_num)
{
THIS_SHOULD_NEVER_HAPPEN;
break;
}
- qdata = (zbx_procstat_query_data_t *)queries.values[i++];
+ qdata = (zbx_procstat_query_data_t *)queries->values[i++];
if (SUCCEED != (query->error = qdata->error))
continue;
@@ -859,11 +816,6 @@ static void procstat_save_cpu_util_snapshot_in_queries(zbx_vector_ptr_t queries,
query->h_data[index].timestamp = snapshot_timestamp;
}
- header->pids_num = pids.values_num;
-
- /* check for free space done at the beginning of the function */
- memcpy(PROCSTAT_SNAPSHOT(procstat_ref.addr), stats, sizeof(zbx_procstat_util_t) * pids.values_num);
-
zbx_dshm_unlock(&collector->procstat);
}
@@ -1036,9 +988,15 @@ void zbx_procstat_collect()
/* number of (non-unique) pids that match queries */
int pids_num = 0;
+ /* flags specifying what process properties must be retrieved */
+ int flags;
+
/* local, working copy of queries */
zbx_vector_ptr_t queries;
+ /* data about all processes on system */
+ zbx_vector_ptr_t processes;
+
/* pids (unique) for which to collect data in this iteration */
zbx_vector_uint64_t pids;
@@ -1051,21 +1009,38 @@ void zbx_procstat_collect()
if (FAIL == zbx_procstat_collector_started() || FAIL == procstat_running())
goto out;
- if (FAIL == procstat_build_local_query_vector(&queries, runid))
- goto out;
+ zbx_vector_ptr_create(&queries);
+ zbx_vector_ptr_create(&processes);
+ zbx_vector_uint64_create(&pids);
+
+ if (ZBX_SYSINFO_PROC_NONE == (flags = procstat_build_local_query_vector(&queries, runid)))
+ goto clean;
- pids_num = procstat_get_pids_matching_query_attributes(queries);
+ if (SUCCEED != zbx_proc_get_processes(&processes, flags))
+ goto clean;
- procstat_build_unique_pids(&pids, queries, pids_num);
+ pids_num = procstat_scan_query_pids(&queries, &processes);
- snapshot_timestamp = procstat_get_cpu_util_snapshot_for_pids(&stats, pids);
+ zbx_vector_uint64_reserve(&pids, pids_num);
+ procstat_get_monitored_pids(&pids, &queries);
- procstat_calculate_cpu_util_for_queries(queries, pids, stats);
+ stats = (zbx_procstat_util_t *)zbx_malloc(NULL, sizeof(zbx_procstat_util_t) * pids.values_num);
+ snapshot_timestamp = procstat_get_cpu_util_snapshot_for_pids(stats, &pids);
- procstat_save_cpu_util_snapshot_in_queries(queries, pids, stats, runid, snapshot_timestamp);
+ procstat_calculate_cpu_util_for_queries(&queries, &pids, stats);
- zbx_free(stats);
+ procstat_save_cpu_util_snapshot_in_queries(&queries, runid, snapshot_timestamp);
+
+ /* replace the current snapshot with the new stats */
+ zbx_free(procstat_snapshot);
+ procstat_snapshot = stats;
+ procstat_snapshot_num = pids.values_num;
+clean:
zbx_vector_uint64_destroy(&pids);
+
+ zbx_proc_free_processes(&processes);
+ zbx_vector_ptr_destroy(&processes);
+
zbx_vector_ptr_clear_ext(&queries, (zbx_mem_free_func_t)procstat_free_query_data);
zbx_vector_ptr_destroy(&queries);