| 1 |
|
/* |
| 2 |
< |
* i-scream central monitoring system |
| 2 |
> |
* i-scream libstatgrab |
| 3 |
|
* http://www.i-scream.org |
| 4 |
|
* Copyright (C) 2000-2004 i-scream |
| 5 |
|
* |
| 65 |
|
#include <limits.h> |
| 66 |
|
#if (defined(FREEBSD) && !defined(FREEBSD5)) || defined(DFBSD) |
| 67 |
|
#include <kvm.h> |
| 68 |
– |
#include <tools.h> |
| 68 |
|
#endif |
| 69 |
|
#include <unistd.h> |
| 70 |
+ |
#ifdef NETBSD2 |
| 71 |
+ |
#include <sys/lwp.h> |
| 72 |
|
#endif |
| 73 |
+ |
#endif |
| 74 |
|
|
| 75 |
|
static void proc_state_init(sg_process_stats *s) { |
| 76 |
|
s->process_name = NULL; |
| 101 |
|
long buflen; |
| 102 |
|
char *p; |
| 103 |
|
#endif |
| 104 |
+ |
#ifdef NETBSD2 |
| 105 |
+ |
int lwps; |
| 106 |
+ |
struct kinfo_lwp *kl_stats; |
| 107 |
|
#endif |
| 108 |
+ |
#endif |
| 109 |
|
#if defined(SOLARIS) || defined(LINUX) |
| 110 |
|
DIR *proc_dir; |
| 111 |
|
struct dirent *dir_entry; |
| 120 |
|
char ps_name[4096]; |
| 121 |
|
char *ptr; |
| 122 |
|
VECTOR_DECLARE_STATIC(psargs, char, 128, NULL, NULL); |
| 123 |
< |
unsigned long stime, utime; |
| 123 |
> |
unsigned long stime, utime, starttime; |
| 124 |
|
int x; |
| 125 |
|
int fn; |
| 126 |
|
int len; |
| 127 |
|
int rc; |
| 128 |
+ |
time_t uptime; |
| 129 |
|
#endif |
| 130 |
|
|
| 131 |
+ |
#ifdef LINUX |
| 132 |
+ |
if ((f=fopen("/proc/uptime", "r")) == NULL) { |
| 133 |
+ |
return NULL; |
| 134 |
+ |
} |
| 135 |
+ |
if((fscanf(f,"%lu %*d",&uptime)) != 1){ |
| 136 |
+ |
return NULL; |
| 137 |
+ |
} |
| 138 |
+ |
fclose(f); |
| 139 |
+ |
#endif |
| 140 |
+ |
|
| 141 |
|
if((proc_dir=opendir(PROC_LOCATION))==NULL){ |
| 142 |
|
return NULL; |
| 143 |
|
} |
| 177 |
|
proc_state_ptr->proc_resident = (process_info.pr_rssize) * 1024; |
| 178 |
|
proc_state_ptr->time_spent = process_info.pr_time.tv_sec; |
| 179 |
|
proc_state_ptr->cpu_percent = (process_info.pr_pctcpu * 100.0) / 0x8000; |
| 180 |
< |
proc_state_ptr->process_name = strdup(process_info.pr_fname); |
| 181 |
< |
proc_state_ptr->proctitle = strdup(process_info.pr_psargs); |
| 180 |
> |
if (sg_update_string(&proc_state_ptr->process_name, |
| 181 |
> |
process_info.pr_fname) < 0) { |
| 182 |
> |
return NULL; |
| 183 |
> |
} |
| 184 |
> |
if (sg_update_string(&proc_state_ptr->proctitle, |
| 185 |
> |
process_info.pr_psargs) < 0) { |
| 186 |
> |
return NULL; |
| 187 |
> |
} |
| 188 |
|
|
| 189 |
|
if(process_info.pr_lwp.pr_state==1) proc_state_ptr->state = SG_PROCESS_STATE_SLEEPING; |
| 190 |
|
if(process_info.pr_lwp.pr_state==2) proc_state_ptr->state = SG_PROCESS_STATE_RUNNING; |
| 193 |
|
if(process_info.pr_lwp.pr_state==6) proc_state_ptr->state = SG_PROCESS_STATE_RUNNING; |
| 194 |
|
#endif |
| 195 |
|
#ifdef LINUX |
| 196 |
< |
x = fscanf(f, "%d %4096s %c %d %d %*d %*d %*d %*u %*u %*u %*u %*u %lu %lu %*d %*d %*d %d %*d %*d %*u %llu %llu %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*d %*d\n", &(proc_state_ptr->pid), ps_name, &s, &(proc_state_ptr->parent), &(proc_state_ptr->pgid), &utime, &stime, &(proc_state_ptr->nice), &(proc_state_ptr->proc_size), &(proc_state_ptr->proc_resident)); |
| 197 |
< |
proc_state_ptr->proc_resident = proc_state_ptr->proc_resident * getpagesize(); |
| 196 |
> |
x = fscanf(f, "%d %4096s %c %d %d %*d %*d %*d %*u %*u %*u %*u %*u %lu %lu %*d %*d %*d %d %*d %*d %lu %llu %llu %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*d %*d\n", &(proc_state_ptr->pid), ps_name, &s, &(proc_state_ptr->parent), &(proc_state_ptr->pgid), &utime, &stime, &(proc_state_ptr->nice), &starttime, &(proc_state_ptr->proc_size), &(proc_state_ptr->proc_resident)); |
| 197 |
> |
/* +3 becuase man page says "Resident Set Size: number of pages the process has in real memory, minus 3 for administrative purposes." */ |
| 198 |
> |
proc_state_ptr->proc_resident = (proc_state_ptr->proc_resident + 3) * getpagesize(); |
| 199 |
|
if(s == 'S') proc_state_ptr->state = SG_PROCESS_STATE_SLEEPING; |
| 200 |
|
if(s == 'R') proc_state_ptr->state = SG_PROCESS_STATE_RUNNING; |
| 201 |
|
if(s == 'Z') proc_state_ptr->state = SG_PROCESS_STATE_ZOMBIE; |
| 211 |
|
return NULL; |
| 212 |
|
} |
| 213 |
|
|
| 214 |
< |
/* Need to do cpu */ |
| 215 |
< |
|
| 214 |
> |
/* cpu */ |
| 215 |
> |
proc_state_ptr->cpu_percent = (100.0 * (utime + stime)) / ((uptime * 100.0) - starttime); |
| 216 |
> |
printf("%s ut: %lu st: %lu up: %lu start: %lu\n", proc_state_ptr->process_name, utime, stime, uptime , starttime); |
| 217 |
|
|
| 218 |
|
fclose(f); |
| 219 |
|
|
| 285 |
|
|
| 286 |
|
procs = size / sizeof(struct kinfo_proc); |
| 287 |
|
|
| 288 |
< |
kp_stats = malloc(size); |
| 288 |
> |
kp_stats = sg_malloc(size); |
| 289 |
|
if(kp_stats == NULL) { |
| 290 |
|
return NULL; |
| 291 |
|
} |
| 292 |
+ |
memset(kp_stats, 0, size); |
| 293 |
|
|
| 294 |
|
if(sysctl(mib, 3, kp_stats, &size, NULL, 0) < 0) { |
| 295 |
|
free(kp_stats); |
| 303 |
|
for (i = 0; i < procs; i++) { |
| 304 |
|
const char *name; |
| 305 |
|
|
| 306 |
+ |
#ifdef FREEBSD5 |
| 307 |
+ |
if (kp_stats[i].ki_stat == 0) { |
| 308 |
+ |
#else |
| 309 |
+ |
if (kp_stats[i].kp_proc.p_stat == 0) { |
| 310 |
+ |
#endif |
| 311 |
+ |
/* FreeBSD 5 deliberately overallocates the array that |
| 312 |
+ |
* the sysctl returns, so we'll get a few junk |
| 313 |
+ |
* processes on the end that we have to ignore. (Search |
| 314 |
+ |
* for "overestimate by 5 procs" in |
| 315 |
+ |
* src/sys/kern/kern_proc.c for more details.) */ |
| 316 |
+ |
continue; |
| 317 |
+ |
} |
| 318 |
+ |
|
| 319 |
|
if (VECTOR_RESIZE(proc_state, proc_state_size + 1) < 0) { |
| 320 |
|
return NULL; |
| 321 |
|
} |
| 340 |
|
return NULL; |
| 341 |
|
} |
| 342 |
|
#else |
| 343 |
+ |
/* FIXME - this value can be too large on some of |
| 344 |
+ |
the BSD's, which causes sysctl not to return |
| 345 |
+ |
anything. Maybe we need something smaller? */ |
| 346 |
|
mib[1] = KERN_ARGMAX; |
| 347 |
|
|
| 348 |
|
if(sysctl(mib, 2, &buflen, &size, NULL, 0) < 0) { |
| 350 |
|
} |
| 351 |
|
#endif |
| 352 |
|
|
| 353 |
< |
proctitle = malloc(buflen); |
| 353 |
> |
proctitle = sg_malloc(buflen); |
| 354 |
|
if(proctitle == NULL) { |
| 355 |
|
return NULL; |
| 356 |
|
} |
| 372 |
|
proc_state_ptr->proctitle = NULL; |
| 373 |
|
} |
| 374 |
|
else if(size > 0) { |
| 375 |
< |
proc_state_ptr->proctitle = malloc(size+1); |
| 375 |
> |
proc_state_ptr->proctitle = sg_malloc(size+1); |
| 376 |
|
if(proc_state_ptr->proctitle == NULL) { |
| 377 |
|
return NULL; |
| 378 |
|
} |
| 401 |
|
argslen += strlen(*argsp) + 1; |
| 402 |
|
argsp++; |
| 403 |
|
} |
| 404 |
< |
proctitle = malloc(argslen + 1); |
| 404 |
> |
proctitle = sg_malloc(argslen + 1); |
| 405 |
|
proctitle[0] = '\0'; |
| 406 |
|
if(proctitle == NULL) { |
| 407 |
|
return NULL; |
| 485 |
|
proc_state_ptr->nice = kp_stats[i].kp_proc.p_nice; |
| 486 |
|
#endif |
| 487 |
|
|
| 488 |
+ |
#ifdef NETBSD2 |
| 489 |
+ |
{ |
| 490 |
+ |
size_t size; |
| 491 |
+ |
int mib[5]; |
| 492 |
+ |
|
| 493 |
+ |
mib[0] = CTL_KERN; |
| 494 |
+ |
mib[1] = KERN_LWP; |
| 495 |
+ |
mib[2] = kp_stats[i].kp_proc.p_pid; |
| 496 |
+ |
mib[3] = sizeof(struct kinfo_lwp); |
| 497 |
+ |
mib[4] = 0; |
| 498 |
+ |
|
| 499 |
+ |
if(sysctl(mib, 5, NULL, &size, NULL, 0) < 0) { |
| 500 |
+ |
return NULL; |
| 501 |
+ |
} |
| 502 |
+ |
|
| 503 |
+ |
lwps = size / sizeof(struct kinfo_lwp); |
| 504 |
+ |
mib[4] = lwps; |
| 505 |
+ |
|
| 506 |
+ |
kl_stats = sg_malloc(size); |
| 507 |
+ |
if(kl_stats == NULL) { |
| 508 |
+ |
return NULL; |
| 509 |
+ |
} |
| 510 |
+ |
|
| 511 |
+ |
if(sysctl(mib, 5, kl_stats, &size, NULL, 0) < 0) { |
| 512 |
+ |
return NULL; |
| 513 |
+ |
} |
| 514 |
+ |
} |
| 515 |
+ |
|
| 516 |
+ |
switch(kp_stats[i].kp_proc.p_stat) { |
| 517 |
+ |
case SIDL: |
| 518 |
+ |
proc_state_ptr->state = SG_PROCESS_STATE_RUNNING; |
| 519 |
+ |
break; |
| 520 |
+ |
case SACTIVE: |
| 521 |
+ |
{ |
| 522 |
+ |
int i; |
| 523 |
+ |
|
| 524 |
+ |
for(i = 0; i < lwps; i++) { |
| 525 |
+ |
switch(kl_stats[i].l_stat) { |
| 526 |
+ |
case LSONPROC: |
| 527 |
+ |
case LSRUN: |
| 528 |
+ |
proc_state_ptr->state = SG_PROCESS_STATE_RUNNING; |
| 529 |
+ |
goto end; |
| 530 |
+ |
case LSSLEEP: |
| 531 |
+ |
proc_state_ptr->state = SG_PROCESS_STATE_SLEEPING; |
| 532 |
+ |
goto end; |
| 533 |
+ |
case LSSTOP: |
| 534 |
+ |
case LSSUSPENDED: |
| 535 |
+ |
proc_state_ptr->state = SG_PROCESS_STATE_STOPPED; |
| 536 |
+ |
goto end; |
| 537 |
+ |
} |
| 538 |
+ |
proc_state_ptr->state = SG_PROCESS_STATE_UNKNOWN; |
| 539 |
+ |
} |
| 540 |
+ |
end: ; |
| 541 |
+ |
} |
| 542 |
+ |
break; |
| 543 |
+ |
case SSTOP: |
| 544 |
+ |
proc_state_ptr->state = SG_PROCESS_STATE_STOPPED; |
| 545 |
+ |
break; |
| 546 |
+ |
case SZOMB: |
| 547 |
+ |
proc_state_ptr->state = SG_PROCESS_STATE_ZOMBIE; |
| 548 |
+ |
break; |
| 549 |
+ |
default: |
| 550 |
+ |
proc_state_ptr->state = SG_PROCESS_STATE_UNKNOWN; |
| 551 |
+ |
break; |
| 552 |
+ |
} |
| 553 |
+ |
#else |
| 554 |
|
#ifdef FREEBSD5 |
| 555 |
|
switch (kp_stats[i].ki_stat) { |
| 556 |
|
#else |
| 585 |
|
proc_state_ptr->state = SG_PROCESS_STATE_UNKNOWN; |
| 586 |
|
break; |
| 587 |
|
} |
| 588 |
+ |
#endif |
| 589 |
|
proc_state_size++; |
| 590 |
|
} |
| 591 |
|
|