diff options
Diffstat (limited to 'src/libs/zbxsysinfo/netbsd/proc.c')
-rw-r--r-- | src/libs/zbxsysinfo/netbsd/proc.c | 694 |
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; } |