summaryrefslogtreecommitdiffstats
path: root/src/libs/zbxsysinfo/netbsd/proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/zbxsysinfo/netbsd/proc.c')
-rw-r--r--src/libs/zbxsysinfo/netbsd/proc.c694
1 files changed, 251 insertions, 443 deletions
diff --git a/src/libs/zbxsysinfo/netbsd/proc.c b/src/libs/zbxsysinfo/netbsd/proc.c
index 081243a1..540d79f7 100644
--- a/src/libs/zbxsysinfo/netbsd/proc.c
+++ b/src/libs/zbxsysinfo/netbsd/proc.c
@@ -18,483 +18,291 @@
* **/
#include "common.h"
-
#include "sysinfo.h"
+#include <sys/sysctl.h>
+
#define DO_SUM 0
#define DO_MAX 1
#define DO_MIN 2
#define DO_AVG 3
-
+
+#define ZBX_PROC_STAT_ALL 0
+#define ZBX_PROC_STAT_RUN 1
+#define ZBX_PROC_STAT_SLEEP 2
+#define ZBX_PROC_STAT_ZOMB 3
+
+static kvm_t *kd = NULL;
+
+static char *proc_argv(pid_t pid)
+{
+ size_t sz = 0;
+ int mib[4], ret;
+ int i, len;
+ static char *argv = NULL;
+ static size_t argv_alloc = 0;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC_ARGS;
+ mib[2] = (int)pid;
+ mib[3] = KERN_PROC_ARGV;
+
+ if (0 != sysctl(mib, 4, NULL, &sz, NULL, 0))
+ return NULL;
+
+ if (argv_alloc < sz) {
+ argv_alloc = sz;
+ if (NULL == argv)
+ argv = zbx_malloc(argv, argv_alloc);
+ else
+ argv = zbx_realloc(argv, argv_alloc);
+ }
+
+ sz = argv_alloc;
+ if (0 != sysctl(mib, 4, argv, &sz, NULL, 0))
+ return NULL;
+
+ for (i = 0; i < (int)(sz - 1); i++ )
+ if (argv[i] == '\0')
+ argv[i] = ' ';
+
+ return argv;
+}
+
int PROC_MEMORY(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result)
{
-#if defined(HAVE_PROC_1_STATUS)
+ char procname[MAX_STRING_LEN],
+ buffer[MAX_STRING_LEN],
+ proccomm[MAX_STRING_LEN],
+ *args;
+ int do_task, pagesize, count, i,
+ proc_ok, comm_ok,
+ op, arg;
+
+ double value = 0.0,
+ memsize = 0;
+ int proccount = 0;
- DIR *dir;
- struct dirent *entries;
- struct stat buf;
- char filename[MAX_STRING_LEN];
- char line[MAX_STRING_LEN];
+ size_t sz;
- char name1[MAX_STRING_LEN];
- char name2[MAX_STRING_LEN];
+ struct kinfo_proc2 *proc, *pproc;
+ struct passwd *usrinfo;
- char procname[MAX_STRING_LEN];
- char usrname[MAX_STRING_LEN];
- char mode[MAX_STRING_LEN];
+ assert(result);
- int proc_ok = 0;
- int usr_ok = 0;
- int do_task = DO_SUM;
+ init_result(result);
+ if (num_param(param) > 4)
+ return SYSINFO_RET_FAIL;
- struct passwd *usrinfo = NULL;
- long long int llvalue = 0;
+ if (0 != get_param(param, 1, procname, sizeof(procname)))
+ *procname = '\0';
+ else if (strlen(procname) > MAXCOMLEN)
+ procname[MAXCOMLEN] = '\0';
- FILE *f;
+ if (0 != get_param(param, 2, buffer, sizeof(buffer)))
+ *buffer = '\0';
- double memsize = -1;
- int proccount = 0;
+ if (*buffer != '\0') {
+ usrinfo = getpwnam(buffer);
+ if (usrinfo == NULL) /* incorrect user name */
+ return SYSINFO_RET_FAIL;
+ } else
+ usrinfo = NULL;
- assert(result);
+ if (0 != get_param(param, 3, buffer, sizeof(buffer)))
+ *buffer = '\0';
- init_result(result);
-
- if(num_param(param) > 3)
- {
- return SYSINFO_RET_FAIL;
- }
+ if (*buffer != '\0') {
+ if (0 == strcmp(buffer, "avg"))
+ do_task = DO_AVG;
+ else if (0 == strcmp(buffer, "max"))
+ do_task = DO_MAX;
+ else if (0 == strcmp(buffer, "min"))
+ do_task = DO_MIN;
+ else if (0 == strcmp(buffer, "sum"))
+ do_task = DO_SUM;
+ else
+ return SYSINFO_RET_FAIL;
+ } else
+ do_task = DO_SUM;
- if(get_param(param, 1, procname, MAX_STRING_LEN) != 0)
- {
- return SYSINFO_RET_FAIL;
- }
-
- if(get_param(param, 2, usrname, MAX_STRING_LEN) != 0)
- {
- usrname[0] = 0;
- }
- else
- {
- if(usrname[0] != 0)
- {
- usrinfo = getpwnam(usrname);
- if(usrinfo == NULL)
- {
- /* incorrect user name */
- return SYSINFO_RET_FAIL;
- }
- }
- }
-
- if(get_param(param, 3, mode, MAX_STRING_LEN) != 0)
- {
- mode[0] = '\0';
- }
-
- if(mode[0] == '\0')
- {
- strscpy(mode, "sum");
- }
-
- if(strcmp(mode,"avg") == 0)
- {
- do_task = DO_AVG;
- }
- else if(strcmp(mode,"max") == 0)
- {
- do_task = DO_MAX;
- }
- else if(strcmp(mode,"min") == 0)
- {
- do_task = DO_MIN;
- }
- else if(strcmp(mode,"sum") == 0)
- {
- do_task = DO_SUM;
- }
- else
- {
- return SYSINFO_RET_FAIL;
- }
-
- dir=opendir("/proc");
- if(NULL == dir)
- {
- return SYSINFO_RET_FAIL;
- }
-
- while((entries=readdir(dir))!=NULL)
- {
- proc_ok = 0;
- usr_ok = 0;
-
- strscpy(filename,"/proc/");
- zbx_strlcat(filename,entries->d_name,MAX_STRING_LEN);
- zbx_strlcat(filename,"/status",MAX_STRING_LEN);
-
- /* Self is a symbolic link. It leads to incorrect results for proc_cnt[zabbix_agentd] */
- /* Better approach: check if /proc/x/ is symbolic link */
- if(strncmp(entries->d_name,"self",MAX_STRING_LEN) == 0)
- {
- continue;
- }
-
- if(stat(filename,&buf)==0)
- {
- if( NULL == (f = fopen(filename,"r") ))
- {
- continue;
- }
-
- if(procname[0] != 0)
- {
- fgets(line,MAX_STRING_LEN,f);
- if(sscanf(line,"%s\t%s\n",name1,name2)==2)
- {
- if(strcmp(name1,"Name:") == 0)
- {
- if(strcmp(procname,name2)==0)
- {
- proc_ok = 1;
- }
- }
- }
-
- if(proc_ok == 0)
- {
- zbx_fclose(f);
- continue;
- }
- }
- else
- {
- proc_ok = 1;
- }
-
- if(usrinfo != NULL)
- {
- while(fgets(line, MAX_STRING_LEN, f) != NULL)
- {
-
- if(sscanf(line, "%s\t%lli\n", name1, &llvalue) != 2)
- {
- continue;
- }
-
- if(strcmp(name1,"Uid:") != 0)
- {
- continue;
- }
-
- if(usrinfo->pw_uid == (uid_t)(llvalue))
- {
- usr_ok = 1;
- break;
- }
- }
- }
- else
- {
- usr_ok = 1;
- }
-
- if(proc_ok && usr_ok)
- {
- while(fgets(line, MAX_STRING_LEN, f) != NULL)
- {
-
- if(sscanf(line, "%s\t%lli %s\n", name1, &llvalue, name2) != 3)
- {
- continue;
- }
-
- if(strcmp(name1,"VmSize:") != 0)
- {
- continue;
- }
-
- proccount++;
-
- if(strcasecmp(name2, "kB") == 0)
- {
- llvalue <<= 10;
- }
- else if(strcasecmp(name2, "mB") == 0)
- {
- llvalue <<= 20;
- }
- else if(strcasecmp(name2, "GB") == 0)
- {
- llvalue <<= 30;
- }
- else if(strcasecmp(name2, "TB") == 0)
- {
- llvalue <<= 40;
- }
-
- if(memsize < 0)
- {
- memsize = (double) llvalue;
- }
- else
- {
- if(do_task == DO_MAX)
- {
- memsize = MAX(memsize, (double) llvalue);
- }
- else if(do_task == DO_MIN)
- {
- memsize = MIN(memsize, (double) llvalue);
- }
- else
- {
- memsize += (double) llvalue;
- }
- }
-
- break;
- }
- }
-
-
- zbx_fclose(f);
- }
- }
- closedir(dir);
-
- if(memsize < 0)
- {
- /* incorrect process name */
- memsize = 0;
- }
-
- if(do_task == DO_AVG)
- {
- SET_DBL_RESULT(result, proccount == 0 ? 0 : ((double)memsize/(double)proccount));
- }
- else
- {
- SET_UI64_RESULT(result, memsize);
- }
- return SYSINFO_RET_OK;
-#else
- return SYSINFO_RET_FAIL;
-#endif
+ if (0 != get_param(param, 4, proccomm, sizeof(proccomm)))
+ *proccomm = '\0';
+
+ pagesize = getpagesize();
+
+ if (NULL == kd && NULL == (kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, NULL)))
+ return SYSINFO_RET_FAIL;
+
+ if (NULL != usrinfo) {
+ op = KERN_PROC_UID;
+ arg = (int)usrinfo->pw_uid;
+ } else {
+ op = KERN_PROC_ALL;
+ arg = 0;
+ }
+
+ if (NULL == (proc = kvm_getproc2(kd, op, arg, sizeof(struct kinfo_proc2), &count)))
+ return SYSINFO_RET_FAIL;
+
+ for (pproc = proc, i = 0; i < count; pproc++, i++) {
+ proc_ok = 0;
+ comm_ok = 0;
+
+ if (*procname == '\0' || 0 == strcmp(procname, pproc->p_comm))
+ proc_ok = 1;
+
+ if (*proccomm != '\0') {
+ if (NULL != (args = proc_argv(pproc->p_pid))) {
+ if (NULL != zbx_regexp_match(args, proccomm, NULL))
+ comm_ok = 1;
+ }
+ } else
+ comm_ok = 1;
+
+ if (proc_ok && comm_ok) {
+ value = pproc->p_vm_tsize
+ + pproc->p_vm_dsize
+ + pproc->p_vm_ssize;
+ value *= pagesize;
+
+ if (0 == proccount++)
+ memsize = value;
+ else {
+ if (do_task == DO_MAX)
+ memsize = MAX(memsize, value);
+ else if (do_task == DO_MIN)
+ memsize = MIN(memsize, value);
+ else
+ memsize += value;
+ }
+ }
+ }
+ zbx_free(proc);
+
+ if (do_task == DO_AVG) {
+ SET_DBL_RESULT(result, proccount == 0 ? 0 : memsize/proccount);
+ } else {
+ SET_UI64_RESULT(result, memsize);
+ }
+
+ return SYSINFO_RET_OK;
}
-int PROC_NUM(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result)
+int PROC_NUM(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result)
{
-#if defined(HAVE_PROC_1_STATUS)
+ char procname[MAX_STRING_LEN],
+ buffer[MAX_STRING_LEN],
+ proccomm[MAX_STRING_LEN],
+ *args;
+ int zbx_proc_stat, count, i,
+ proc_ok, stat_ok, comm_ok,
+ op, arg;
- DIR *dir;
- struct dirent *entries;
- struct stat buf;
- char filename[MAX_STRING_LEN];
- char line[MAX_STRING_LEN];
+ int proccount = 0;
- char name1[MAX_STRING_LEN];
- char name2[MAX_STRING_LEN];
+ size_t sz;
- char procname[MAX_STRING_LEN];
- char usrname[MAX_STRING_LEN];
- char procstat[MAX_STRING_LEN];
+ struct kinfo_proc2 *proc, *pproc;
+ struct passwd *usrinfo;
- int proc_ok = 0;
- int usr_ok = 0;
- int stat_ok = 0;
+ assert(result);
- struct passwd *usrinfo = NULL;
- long int lvalue = 0;
+ init_result(result);
- FILE *f;
- int proccount = 0;
+ if (num_param(param) > 4)
+ return SYSINFO_RET_FAIL;
- assert(result);
+ if (0 != get_param(param, 1, procname, sizeof(procname)))
+ *procname = '\0';
+ else if (strlen(procname) > MAXCOMLEN)
+ procname[MAXCOMLEN] = '\0';
- init_result(result);
-
-
- if(num_param(param) > 3)
- {
- return SYSINFO_RET_FAIL;
- }
-
- if(get_param(param, 1, procname, MAX_STRING_LEN) != 0)
- {
- return SYSINFO_RET_FAIL;
- }
-
- if(get_param(param, 2, usrname, MAX_STRING_LEN) != 0)
- {
- usrname[0] = 0;
- }
- else
- {
- if(usrname[0] != 0)
- {
- usrinfo = getpwnam(usrname);
- if(usrinfo == NULL)
- {
- /* incorrect user name */
- return SYSINFO_RET_FAIL;
- }
- }
- }
+ if (0 != get_param(param, 2, buffer, sizeof(buffer)))
+ *buffer = '\0';
+
+ if (*buffer != '\0') {
+ usrinfo = getpwnam(buffer);
+ if (usrinfo == NULL) /* incorrect user name */
+ return SYSINFO_RET_FAIL;
+ } else
+ usrinfo = NULL;
- if(get_param(param, 3, procstat, MAX_STRING_LEN) != 0)
- {
- procstat[0] = '\0';
+ if (0 != get_param(param, 3, buffer, sizeof(buffer)))
+ *buffer = '\0';
+
+ if (*buffer != '\0') {
+ if (0 == strcmp(buffer, "run"))
+ zbx_proc_stat = ZBX_PROC_STAT_RUN;
+ else if (0 == strcmp(buffer, "sleep"))
+ zbx_proc_stat = ZBX_PROC_STAT_SLEEP;
+ else if (0 == strcmp(buffer, "zomb"))
+ zbx_proc_stat = ZBX_PROC_STAT_ZOMB;
+ else if (0 == strcmp(buffer, "all"))
+ zbx_proc_stat = ZBX_PROC_STAT_ALL;
+ else
+ return SYSINFO_RET_FAIL;
+ } else
+ zbx_proc_stat = ZBX_PROC_STAT_ALL;
+
+ if (0 != get_param(param, 4, proccomm, sizeof(proccomm)))
+ *proccomm = '\0';
+
+ if (NULL == kd && NULL == (kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, NULL)))
+ return SYSINFO_RET_FAIL;
+
+ if (NULL != usrinfo) {
+ op = KERN_PROC_UID;
+ arg = (int)usrinfo->pw_uid;
+ } else {
+ op = KERN_PROC_ALL;
+ arg = 0;
}
- if(procstat[0] == '\0')
- {
- strscpy(procstat, "all");
- }
-
- if(strcmp(procstat,"run") == 0)
- {
- strscpy(procstat,"R");
- }
- else if(strcmp(procstat,"sleep") == 0)
- {
- strscpy(procstat,"S");
- }
- else if(strcmp(procstat,"zomb") == 0)
- {
- strscpy(procstat,"Z");
- }
- else if(strcmp(procstat,"all") == 0)
- {
- procstat[0] = 0;
- }
- else
- {
- return SYSINFO_RET_FAIL;
- }
+ if (NULL == (proc = kvm_getproc2(kd, op, arg, sizeof(struct kinfo_proc2), &count)))
+ return SYSINFO_RET_FAIL;
+
+ for (pproc = proc, i = 0; i < count; pproc++, i++) {
+ proc_ok = 0;
+ stat_ok = 0;
+ comm_ok = 0;
+
+ if (*procname == '\0' || 0 == strcmp(procname, pproc->p_comm))
+ proc_ok = 1;
+
+ if (zbx_proc_stat != ZBX_PROC_STAT_ALL) {
+ switch (zbx_proc_stat) {
+ case ZBX_PROC_STAT_RUN:
+ if (pproc->p_stat == LSRUN || pproc->p_stat == LSONPROC)
+ stat_ok = 1;
+ break;
+ case ZBX_PROC_STAT_SLEEP:
+ if (pproc->p_stat == LSSLEEP)
+ stat_ok = 1;
+ break;
+ case ZBX_PROC_STAT_ZOMB:
+ if (pproc->p_stat == SZOMB || pproc->p_stat == LSDEAD)
+ stat_ok = 1;
+ break;
+ }
+ } else
+ stat_ok = 1;
+
+ if (*proccomm != '\0') {
+ if (NULL != (args = proc_argv(pproc->p_pid))) {
+ if (zbx_regexp_match(args, proccomm, NULL) != NULL)
+ comm_ok = 1;
+ }
+ } else
+ comm_ok = 1;
- dir=opendir("/proc");
- if(NULL == dir)
- {
- return SYSINFO_RET_FAIL;
- }
-
- while((entries=readdir(dir))!=NULL)
- {
- proc_ok = 0;
- stat_ok = 0;
- usr_ok = 0;
-
-/* Self is a symbolic link. It leads to incorrect results for proc_cnt[zabbix_agentd] */
-/* Better approach: check if /proc/x/ is symbolic link */
- if(strncmp(entries->d_name,"self",MAX_STRING_LEN) == 0)
- {
- continue;
- }
-
- strscpy(filename,"/proc/");
- zbx_strlcat(filename,entries->d_name,MAX_STRING_LEN);
- zbx_strlcat(filename,"/status",MAX_STRING_LEN);
-
- if(stat(filename,&buf)==0)
- {
- if(NULL == (f = fopen(filename,"r") ))
- {
- continue;
- }
-
- if(procname[0] != 0)
- {
- fgets(line,MAX_STRING_LEN,f);
- if(sscanf(line,"%s\t%s\n",name1,name2)==2)
- {
- if(strcmp(name1,"Name:") == 0)
- {
- if(strcmp(procname,name2)==0)
- {
- proc_ok = 1;
- }
- }
- }
-
- if(proc_ok == 0)
- {
- zbx_fclose(f);
- continue;
- }
- }
- else
- {
- proc_ok = 1;
- }
-
- if(procstat[0] != 0)
- {
- while(fgets(line, MAX_STRING_LEN, f) != NULL)
- {
-
- if(sscanf(line, "%s\t%s\n", name1, name2) != 2)
- {
- continue;
- }
-
- if(strcmp(name1,"State:") != 0)
- {
- continue;
- }
-
- if(strcmp(name2, procstat))
- {
- stat_ok = 1;
- break;
- }
- }
- }
- else
- {
- stat_ok = 1;
- }
-
- if(usrinfo != NULL)
- {
- while(fgets(line, MAX_STRING_LEN, f) != NULL)
- {
-
- if(sscanf(line, "%s\t%li\n", name1, &lvalue) != 2)
- {
- continue;
- }
-
- if(strcmp(name1,"Uid:") != 0)
- {
- continue;
- }
-
- if(usrinfo->pw_uid == (uid_t)(lvalue))
- {
- usr_ok = 1;
- break;
- }
- }
- }
- else
- {
- usr_ok = 1;
- }
-
- if(proc_ok && stat_ok && usr_ok)
- {
- proccount++;
- }
-
- zbx_fclose(f);
- }
- }
- closedir(dir);
+ if (proc_ok && stat_ok && comm_ok)
+ proccount++;
+ }
+ zbx_free(proc);
SET_UI64_RESULT(result, proccount);
- return SYSINFO_RET_OK;
-#else
- return SYSINFO_RET_FAIL;
-#endif
+
+ return SYSINFO_RET_OK;
}