29
int PROC_MEMORY(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result)
30
{ /* usage: <function name>[ <process name>, <user name>, <mode>, <command> ] */
33
struct dirent *entries;
35
char filename[MAX_STRING_LEN];
36
char line[MAX_STRING_LEN];
38
char name1[MAX_STRING_LEN];
39
char name2[MAX_STRING_LEN];
41
char proccomm[MAX_STRING_LEN];
42
char procname[MAX_STRING_LEN];
43
char usrname[MAX_STRING_LEN];
44
char mode[MAX_STRING_LEN];
53
struct passwd *usrinfo = NULL;
54
zbx_uint64_t llvalue = 0;
56
FILE *f = NULL, *f2 = NULL;
58
zbx_uint64_t memsize = 0;
60
zbx_uint64_t proccount = 0;
29
#define ZBX_PROC_STAT_ALL 0
30
#define ZBX_PROC_STAT_RUN 1
31
#define ZBX_PROC_STAT_SLEEP 2
32
#define ZBX_PROC_STAT_ZOMB 3
34
static FILE *open_proc_file(const char *filename)
38
if (0 != stat(filename, &s))
41
return fopen(filename, "r");
44
static int get_cmdline(FILE *f_cmd, char *line, size_t *n)
48
if (0 != (*n = fread(line, 1, MAX_STRING_LEN, f_cmd)))
54
static int get_procname(FILE *f_stat, char *line)
56
char tmp[MAX_STRING_LEN], *p;
60
while (NULL != fgets(tmp, sizeof(tmp), f_stat)) {
61
if (NULL == (p = strchr(tmp, '\t')))
66
if (0 != strcmp(tmp, "Name:"))
70
zbx_strlcpy(line, p, MAX_STRING_LEN);
77
static int check_procname(FILE *f_cmd, FILE *f_stat, const char *procname)
79
char tmp[MAX_STRING_LEN], *p;
82
if (*procname == '\0')
85
if (SUCCEED == get_cmdline(f_cmd, tmp, &l)) {
86
if (NULL == (p = strrchr(tmp, '/')))
91
if (0 == strcmp(p, procname))
93
} else if (SUCCEED == get_procname(f_stat, tmp)) {
94
if (0 == strcmp(tmp, procname))
101
static int check_user(FILE *f_stat, struct passwd *usrinfo)
103
char tmp[MAX_STRING_LEN], *p, *p1;
111
while (NULL != fgets(tmp, sizeof(tmp), f_stat)) {
112
if (NULL == (p = strchr(tmp, '\t')))
117
if (0 != strcmp(tmp, "Uid:"))
120
if (NULL != (p1 = strchr(p, '\t')))
123
uid = (uid_t)atoi(p);
124
if (usrinfo->pw_uid == uid)
132
static int check_proccomm(FILE *f_cmd, const char *proccomm)
134
char tmp[MAX_STRING_LEN];
137
if (*proccomm == '\0')
140
if (SUCCEED == get_cmdline(f_cmd, tmp, &l)) {
141
for (i = 0; i < l - 1; i++)
145
if (NULL != zbx_regexp_match(tmp, proccomm, NULL))
152
static int check_procstate(FILE *f_stat, int zbx_proc_stat)
154
char tmp[MAX_STRING_LEN], *p;
156
if (zbx_proc_stat == ZBX_PROC_STAT_ALL)
161
while (NULL != fgets(tmp, sizeof(tmp), f_stat)) {
162
if (NULL == (p = strchr(tmp, '\t')))
167
if (0 != strcmp(tmp, "State:"))
170
switch (zbx_proc_stat) {
171
case ZBX_PROC_STAT_RUN:
172
return (*p == 'R') ? SUCCEED : FAIL;
173
case ZBX_PROC_STAT_SLEEP:
174
return (*p == 'S') ? SUCCEED : FAIL;
175
case ZBX_PROC_STAT_ZOMB:
176
return (*p == 'Z') ? SUCCEED : FAIL;
184
int PROC_MEMORY(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result)
186
char tmp[MAX_STRING_LEN], *p, *p1,
187
procname[MAX_STRING_LEN],
188
buffer[MAX_STRING_LEN],
189
proccomm[MAX_STRING_LEN];
191
struct dirent *entries;
192
struct passwd *usrinfo;
193
FILE *f_cmd = NULL, *f_stat = NULL;
194
zbx_uint64_t value = 0;
64
201
init_result(result);
66
if(num_param(param) > 4)
68
return SYSINFO_RET_FAIL;
71
if(get_param(param, 1, procname, MAX_STRING_LEN) != 0)
73
return SYSINFO_RET_FAIL;
76
if(get_param(param, 2, usrname, MAX_STRING_LEN) != 0)
84
usrinfo = getpwnam(usrname);
87
/* incorrect user name */
88
return SYSINFO_RET_FAIL;
93
if(get_param(param, 3, mode, MAX_STRING_LEN) != 0)
100
strscpy(mode, "sum");
103
if(strcmp(mode,"avg") == 0)
107
else if(strcmp(mode,"max") == 0)
111
else if(strcmp(mode,"min") == 0)
115
else if(strcmp(mode,"sum") == 0)
203
if (num_param(param) > 4)
204
return SYSINFO_RET_FAIL;
206
if (0 != get_param(param, 1, procname, sizeof(procname)))
209
if (0 != get_param(param, 2, buffer, sizeof(buffer)))
212
if (*buffer != '\0') {
213
usrinfo = getpwnam(buffer);
214
if (usrinfo == NULL) /* incorrect user name */
215
return SYSINFO_RET_FAIL;
219
if (0 != get_param(param, 3, buffer, sizeof(buffer)))
222
if (*buffer != '\0') {
223
if (0 == strcmp(buffer, "avg"))
225
else if (0 == strcmp(buffer, "max"))
227
else if (0 == strcmp(buffer, "min"))
229
else if (0 == strcmp(buffer, "sum"))
232
return SYSINFO_RET_FAIL;
117
234
do_task = DO_SUM;
121
return SYSINFO_RET_FAIL;
124
if(get_param(param, 4, proccomm, MAX_STRING_LEN) != 0)
130
dir=opendir("/proc");
133
return SYSINFO_RET_FAIL;
136
while((entries=readdir(dir))!=NULL)
143
strscpy(filename,"/proc/");
144
zbx_strlcat(filename,entries->d_name,MAX_STRING_LEN);
145
zbx_strlcat(filename,"/status",MAX_STRING_LEN);
236
if (0 != get_param(param, 4, proccomm, sizeof(proccomm)))
239
if (NULL == (dir = opendir("/proc")))
240
return SYSINFO_RET_FAIL;
242
while (NULL != (entries = readdir(dir))) {
147
246
/* Self is a symbolic link. It leads to incorrect results for proc_cnt[zabbix_agentd] */
148
247
/* Better approach: check if /proc/x/ is symbolic link */
149
if(strncmp(entries->d_name,"self",MAX_STRING_LEN) == 0)
154
if(stat(filename,&buf)==0)
156
if(NULL == ( f = fopen(filename,"r") ))
163
if(NULL == fgets(line,MAX_STRING_LEN,f))
167
if(sscanf(line,"%s\t%s\n",name1,name2)==2)
169
if(strcmp(name1,"Name:") == 0)
171
if(strcmp(procname,name2)==0)
190
while(fgets(line, MAX_STRING_LEN, f) != NULL)
193
if(sscanf(line, "%s\t" ZBX_FS_UI64 "\n", name1, &llvalue) != 2)
198
if(strcmp(name1,"Uid:") != 0)
203
if(usrinfo->pw_uid == (uid_t)(llvalue))
216
if(proccomm[0] != '\0')
218
strscpy(filename,"/proc/");
219
zbx_strlcat(filename,entries->d_name,MAX_STRING_LEN);
220
zbx_strlcat(filename,"/cmdline",MAX_STRING_LEN);
222
if(stat(filename,&buf)!=0) continue;
224
f2=fopen(filename,"r");
225
if(f2==NULL) continue;
227
memset(line,0,MAX_STRING_LEN);
228
if((n = fread(line, 1, MAX_STRING_LEN, f2)) != 0)
230
/* Replace all zero delimiters with spaces */
233
if(line[i]==0) line[i]=' ';
235
if(zbx_regexp_match(line,proccomm,NULL) != NULL)
244
if(proc_ok && usr_ok && comm_ok)
246
while(fgets(line, MAX_STRING_LEN, f) != NULL)
249
if(sscanf(line, "%s\t" ZBX_FS_UI64 " %s\n", name1, &llvalue, name2) != 3)
254
if(strcmp(name1,"VmSize:") != 0)
261
if(strcasecmp(name2, "kB") == 0)
265
else if(strcasecmp(name2, "mB") == 0)
269
else if(strcasecmp(name2, "GB") == 0)
273
else if(strcasecmp(name2, "TB") == 0)
285
if(do_task == DO_MAX)
287
memsize = MAX(memsize, llvalue);
289
else if(do_task == DO_MIN)
291
memsize = MIN(memsize, llvalue);
248
if (0 == strncmp(entries->d_name, "self", MAX_STRING_LEN))
251
zbx_snprintf(tmp, sizeof(tmp), "/proc/%s/cmdline", entries->d_name);
253
if (NULL == (f_cmd = open_proc_file(tmp)))
256
zbx_snprintf(tmp, sizeof(tmp), "/proc/%s/status", entries->d_name);
258
if (NULL == (f_stat = open_proc_file(tmp)))
261
if (FAIL == check_procname(f_cmd, f_stat, procname))
264
if (FAIL == check_user(f_stat, usrinfo))
267
if (FAIL == check_proccomm(f_cmd, proccomm))
272
while (NULL != fgets(tmp, sizeof(tmp), f_stat)) {
273
if (NULL == (p = strchr(tmp, '\t')))
278
if (0 != strcmp(tmp, "VmSize:"))
281
if (NULL == (p1 = strrchr(p, ' ')))
286
value = zbx_atoui64(p);
290
if (0 == strcasecmp(p1, "kB"))
292
else if(0 == strcasecmp(p1, "mB"))
294
else if(0 == strcasecmp(p1, "GB"))
296
else if(0 == strcasecmp(p1, "TB"))
299
if (0 == proccount++)
302
if (do_task == DO_MAX)
303
memsize = MAX(memsize, value);
304
else if(do_task == DO_MIN)
305
memsize = MIN(memsize, value);
309
/* incorrect process name */
313
if(do_task == DO_AVG)
315
SET_DBL_RESULT(result, proccount == 0 ? 0 : ((double)memsize/(double)proccount));
316
if (do_task == DO_AVG) {
317
SET_DBL_RESULT(result, proccount == 0 ? 0 : memsize/proccount);
319
319
SET_UI64_RESULT(result, memsize);
321
322
return SYSINFO_RET_OK;
324
325
int PROC_NUM(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result)
325
{ /* usage: <function name>[ <process name>, <user name>, <process state>, <command> ] */
328
struct dirent *entries;
330
char filename[MAX_STRING_LEN];
331
char line[MAX_STRING_LEN];
333
char name1[MAX_STRING_LEN];
334
char name2[MAX_STRING_LEN];
336
char proccomm[MAX_STRING_LEN];
337
char procname[MAX_STRING_LEN];
338
char usrname[MAX_STRING_LEN];
339
char procstat[MAX_STRING_LEN];
348
struct passwd *usrinfo = NULL;
327
char tmp[MAX_STRING_LEN],
328
procname[MAX_STRING_LEN],
329
buffer[MAX_STRING_LEN],
330
proccomm[MAX_STRING_LEN];
332
struct dirent *entries;
333
struct passwd *usrinfo;
334
FILE *f_cmd = NULL, *f_stat = NULL;
352
336
zbx_uint64_t proccount = 0;
358
if(num_param(param) > 4)
360
return SYSINFO_RET_FAIL;
363
if(get_param(param, 1, procname, MAX_STRING_LEN) != 0)
365
return SYSINFO_RET_FAIL;
369
if(get_param(param, 2, usrname, MAX_STRING_LEN) != 0)
377
usrinfo = getpwnam(usrname);
380
/* incorrect user name */
381
return SYSINFO_RET_FAIL;
386
if(get_param(param, 3, procstat, MAX_STRING_LEN) != 0)
391
if(procstat[0] == '\0')
393
strscpy(procstat, "all");
396
if(strcmp(procstat,"run") == 0)
398
strscpy(procstat,"R");
400
else if(strcmp(procstat,"sleep") == 0)
402
strscpy(procstat,"S");
404
else if(strcmp(procstat,"zomb") == 0)
406
strscpy(procstat,"Z");
408
else if(strcmp(procstat,"all") == 0)
414
return SYSINFO_RET_FAIL;
417
if(get_param(param, 4, proccomm, MAX_STRING_LEN) != 0)
422
dir=opendir("/proc");
425
return SYSINFO_RET_FAIL;
428
while((entries=readdir(dir))!=NULL)
431
/* Self is a symbolic link. It leads to incorrect results for proc_cnt[zabbix_agentd] */
432
/* Better approach: check if /proc/x/ is symbolic link */
433
if(strncmp(entries->d_name,"self",MAX_STRING_LEN) == 0)
438
strscpy(filename,"/proc/");
439
zbx_strlcat(filename,entries->d_name,MAX_STRING_LEN);
440
zbx_strlcat(filename,"/status",MAX_STRING_LEN);
442
if(stat(filename,&buf)!=0)
447
if(NULL == (f = fopen(filename,"r") ))
455
if(NULL == fgets(line,MAX_STRING_LEN,f))
459
if(sscanf(line,"%s\t%s\n",name1,name2)==2)
461
if(strcmp(name1,"Name:") == 0)
463
if(strcmp(procname,name2)==0)
484
while(fgets(line, MAX_STRING_LEN, f) != NULL)
487
if(sscanf(line, "%s\t%s\n", name1, name2) != 2)
492
if(strcmp(name1,"State:") != 0)
497
if(strcmp(name2, procstat) == 0)
512
while(fgets(line, MAX_STRING_LEN, f) != NULL)
515
if(sscanf(line, "%s\t%li\n", name1, &lvalue) != 2)
520
if(strcmp(name1,"Uid:") != 0)
525
if(usrinfo->pw_uid == (uid_t)(lvalue))
343
if (num_param(param) > 4)
344
return SYSINFO_RET_FAIL;
346
if (0 != get_param(param, 1, procname, sizeof(procname)))
349
if (0 != get_param(param, 2, buffer, sizeof(buffer)))
352
if (*buffer != '\0') {
353
usrinfo = getpwnam(buffer);
354
if (usrinfo == NULL) /* incorrect user name */
355
return SYSINFO_RET_FAIL;
359
if (0 != get_param(param, 3, buffer, sizeof(buffer)))
539
if(proccomm[0] != '\0')
541
strscpy(filename,"/proc/");
542
zbx_strlcat(filename,entries->d_name,MAX_STRING_LEN);
543
zbx_strlcat(filename,"/cmdline",MAX_STRING_LEN);
545
if(stat(filename,&buf)!=0) continue;
547
f=fopen(filename,"r");
548
if(f==NULL) continue;
550
memset(line,0,MAX_STRING_LEN);
551
if((n = fread(line, 1, MAX_STRING_LEN, f)) != 0)
553
/* Replace all zero delimiters with spaces */
556
if(line[i]==0) line[i]=' ';
558
if(zbx_regexp_match(line,proccomm,NULL) != NULL)
567
if(proc_ok && stat_ok && usr_ok && comm_ok)
362
if (*buffer != '\0') {
363
if (0 == strcmp(buffer, "run"))
364
zbx_proc_stat = ZBX_PROC_STAT_RUN;
365
else if (0 == strcmp(buffer, "sleep"))
366
zbx_proc_stat = ZBX_PROC_STAT_SLEEP;
367
else if (0 == strcmp(buffer, "zomb"))
368
zbx_proc_stat = ZBX_PROC_STAT_ZOMB;
369
else if (0 == strcmp(buffer, "all"))
370
zbx_proc_stat = ZBX_PROC_STAT_ALL;
372
return SYSINFO_RET_FAIL;
374
zbx_proc_stat = ZBX_PROC_STAT_ALL;
376
if (0 != get_param(param, 4, proccomm, sizeof(proccomm)))
379
if (NULL == (dir = opendir("/proc")))
380
return SYSINFO_RET_FAIL;
382
while (NULL != (entries = readdir(dir))) {
386
/* Self is a symbolic link. It leads to incorrect results for proc_cnt[zabbix_agentd] */
387
/* Better approach: check if /proc/x/ is symbolic link */
388
if (0 == strncmp(entries->d_name, "self", MAX_STRING_LEN))
391
zbx_snprintf(tmp, sizeof(tmp), "/proc/%s/cmdline", entries->d_name);
393
if (NULL == (f_cmd = open_proc_file(tmp)))
396
zbx_snprintf(tmp, sizeof(tmp), "/proc/%s/status", entries->d_name);
398
if (NULL == (f_stat = open_proc_file(tmp)))
401
if (FAIL == check_procname(f_cmd, f_stat, procname))
404
if (FAIL == check_user(f_stat, usrinfo))
407
if (FAIL == check_proccomm(f_cmd, proccomm))
410
if (FAIL == check_procstate(f_stat, zbx_proc_stat))
575
419
SET_UI64_RESULT(result, proccount);
576
421
return SYSINFO_RET_OK;