00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022
00023 #ifdef HAVE_SYS_TYPES_H
00024 #include <sys/types.h>
00025 #endif
00026
00027 #include <unistd.h>
00028
00029 #ifdef HAVE_SYS_STAT_H
00030 #include <sys/stat.h>
00031 #endif
00032
00033 #ifdef HAVE_FCNTL_H
00034 #include <fcntl.h>
00035 #endif
00036
00037 #ifdef HAVE_STDLIB_H
00038 #include <stdlib.h>
00039 #endif
00040
00041 #ifdef TIME_WITH_SYS_TIME
00042 #include <time.h>
00043
00044 #ifdef HAVE_SYS_TIME_H
00045 #include <sys/time.h>
00046 #endif
00047 #else
00048 #include <time.h>
00049 #endif
00050
00051 #ifdef HAVE_STRING_H
00052 #include <string.h>
00053 #endif
00054
00055 #include <stdio.h>
00056
00057
00058 #ifdef SOLARIS
00059 #include <procfs.h>
00060 #endif
00061
00062 #ifdef FREEBSD
00063 #include <kvm.h>
00064 #include <sys/param.h>
00065 #include <sys/proc.h>
00066 #include <sys/resource.h>
00067 #include <sys/resourcevar.h>
00068 #include <sys/lock.h>
00069 #include <sys/user.h>
00070 #include <vm/vm.h>
00071 #include <vm/vm_object.h>
00072 #include <vm/pmap.h>
00073 #include <machine/pmap.h>
00074 #include <machine/vmparam.h>
00075 #include <vm/vm_map.h>
00076 #include <sys/vmmeter.h>
00077 #include <sys/sysctl.h>
00078 #endif
00079
00080 #ifdef DARWIN
00081 #include <kvm.h>
00082 #include <sys/param.h>
00083 #include <sys/proc.h>
00084 #include <sys/resource.h>
00085 #include <sys/resourcevar.h>
00086 #include <sys/lock.h>
00087 #include <sys/user.h>
00088 #include <machine/vmparam.h>
00089 #include <sys/vmmeter.h>
00090 #include <sys/sysctl.h>
00091 #endif
00092
00093 #ifdef LINUX
00094 #include <asm/param.h>
00095 #include <asm/page.h>
00096 #endif
00097
00098
00099 #include "process.h"
00100
00112
00113
00114 #ifdef SOLARIS
00115
00116 int init_process_info_sysdep(void) {
00117
00118 num_cpus= sysconf( _SC_NPROCESSORS_ONLN);
00119
00120 return (getuid()==0);
00121
00122 }
00123
00124 double timestruc_to_tseconds(timestruc_t t) {
00125 return t.tv_sec * 10 + t.tv_nsec / 100000000.0;
00126 }
00127
00128 int get_process_info_sysdep(ProcInfo_T p) {
00129
00130 char buf[4096];
00131 psinfo_t * psinfo= (psinfo_t *)&buf;
00132 pstatus_t * pstatus= (pstatus_t *)&buf;
00133
00134 if (!read_proc_file(buf,4096, "psinfo", p->pid)) {
00135
00136 return FALSE;
00137
00138 }
00139
00140
00141
00142
00143 if ( psinfo->pr_nlwp == 0 ) {
00144
00145 p->status_flag = PROCESS_ZOMBIE;
00146
00147 }
00148
00149
00150 if ( p->status_flag != PROCESS_ZOMBIE ) {
00151
00152
00153
00154 p->mem_percent = psinfo->pr_pctmem * 1000 / 0x8000;
00155 p->mem_kbyte = psinfo->pr_rssize;
00156
00157 if (!read_proc_file(buf,4096, "status", p->pid)) {
00158
00159 return FALSE;
00160
00161 }
00162
00163 p->cputime_prev= p->cputime;
00164 p->cputime= ( timestruc_to_tseconds(pstatus->pr_utime) +
00165 timestruc_to_tseconds(pstatus->pr_stime) );
00166
00167 if( include_children ) {
00168
00169 p->cputime+= ( timestruc_to_tseconds(pstatus->pr_cutime) +
00170 timestruc_to_tseconds(pstatus->pr_cstime) );
00171
00172 }
00173
00174
00175 if ( p->time_prev == 0.0 ) {
00176
00177 p->cputime_prev= p->cputime;
00178
00179 }
00180
00181 } else {
00182
00183 p->cputime_prev= p->cputime = 0;
00184 p->mem_kbyte= 0;
00185 p->mem_percent= 0.0;
00186
00187 }
00188
00189 return TRUE;
00190 }
00191
00192 #endif
00193
00194 #ifdef LINUX
00195
00196 #define PAGE_TO_KBYTE_SHIFT PAGE_SHIFT-10
00197
00198 static long mem_kbyte_max;
00199
00200 int init_process_info_sysdep(void) {
00201
00202 struct stat buf;
00203
00204
00205
00206
00207 if ( stat("/proc/kcore", &buf) != 0 ) {
00208
00209 return FALSE;
00210
00211 }
00212
00213 num_cpus= sysconf(_SC_NPROCESSORS_CONF);
00214
00215 mem_kbyte_max = buf.st_size>>10;
00216
00217 return TRUE;
00218
00219 }
00220
00221
00222 int get_process_info_sysdep(ProcInfo_T p) {
00223
00224 char buf[4096];
00225 char* tmp;
00226 char stat_item_state;
00227 unsigned long stat_item_utime;
00228 unsigned long stat_item_stime;
00229 long stat_item_cutime;
00230 long stat_item_cstime;
00231 long stat_item_rss;
00232
00233 if (!read_proc_file(buf,4096, "stat", p->pid)) {
00234
00235 return FALSE;
00236
00237 }
00238
00239
00240
00241 tmp = strrchr(buf, ')') + 2;
00242
00243
00244
00245
00246 sscanf(tmp,"%c %*d %*d %*d %*d %*d %*u %*u"
00247 "%*u %*u %*u %lu %lu %ld %ld %*d %*d %*d "
00248 "%*d %*u %*u %ld %*u %*u %*u %*u %*u "
00249 "%*u %*u %*u %*u %*u %*u %*u %*u %*d %*d\n",
00250 &stat_item_state, &stat_item_utime, &stat_item_stime,
00251 &stat_item_cutime, &stat_item_cstime, &stat_item_rss);
00252
00253
00254
00255
00256 if ( PAGE_TO_KBYTE_SHIFT < 0 ) {
00257
00258 p->mem_kbyte= stat_item_rss >> abs(PAGE_TO_KBYTE_SHIFT);
00259
00260 } else {
00261
00262 p->mem_kbyte= stat_item_rss << abs(PAGE_TO_KBYTE_SHIFT);
00263
00264 }
00265
00266 p->mem_percent = (int) ((double) p->mem_kbyte * 1000.0 / mem_kbyte_max);
00267
00268
00269
00270
00271
00272 p->cputime_prev = p->cputime;
00273 p->cputime = ( stat_item_utime + stat_item_stime ) * 10 / HZ;
00274
00275 if ( include_children ) {
00276
00277 p->cputime += ( stat_item_cutime + stat_item_cstime ) * 10 / HZ;
00278
00279 }
00280
00281
00282
00283 if ( p->time_prev == 0.0 ) {
00284
00285 p->cputime_prev = p->cputime;
00286
00287 }
00288
00289
00290
00291 if ( stat_item_state == 'Z' ) {
00292
00293 p->status_flag |= PROCESS_ZOMBIE;
00294
00295 }
00296
00297 return TRUE;
00298
00299 }
00300
00301 #endif
00302
00303 #ifdef FREEBSD
00304
00305 #define pagetok(size) ((size) << pageshift)
00306 #define tv2sec(tv) (((u_int64_t) tv.tv_sec * 1000000) + (u_int64_t) tv.tv_usec)
00307
00308 static int pageshift;
00309 static long mem_kbyte_max;
00310
00311 #ifndef LOG1024
00312 #define LOG1024 10
00313 #endif
00314
00315 static kvm_t * kvm_handle;
00316
00317 static void calcru(struct proc *p, struct timeval *up, struct timeval *sp,
00318 struct timeval *ip)
00319 {
00320 quad_t totusec;
00321 u_quad_t u, st, ut, it, tot;
00322 #if (__FreeBSD_version < 300003)
00323 long sec, usec;
00324 #endif
00325
00326 st = p->p_sticks;
00327 ut = p->p_uticks;
00328 it = p->p_iticks;
00329
00330 tot = st + ut + it;
00331 if (tot == 0)
00332 {
00333 st = 1;
00334 tot = 1;
00335 }
00336
00337 #if (defined __FreeBSD__) && (__FreeBSD_version >= 300003)
00338 totusec = (u_quad_t) p->p_runtime;
00339 #else
00340 sec = p->p_rtime.tv_usec;
00341 usec = p->p_rtime.tv_usec;
00342
00343 totusec = (quad_t)sec * 1000000 + usec;
00344 #endif
00345
00346 if(totusec < 0)
00347 {
00348 fprintf (stderr, "calcru: negative time: %ld usec\n",
00349 (long)totusec);
00350 totusec = 0;
00351 }
00352
00353 u = totusec;
00354 st = (u * st) / tot;
00355 sp->tv_sec = st / 1000000;
00356 sp->tv_usec = st % 1000000;
00357 ut = (u * ut) / tot;
00358 up->tv_sec = ut / 1000000;
00359 up->tv_usec = ut % 1000000;
00360
00361 if(ip != NULL)
00362 {
00363 it = (u * it) / tot;
00364 ip->tv_sec = it / 1000000;
00365 ip->tv_usec = it % 1000000;
00366 }
00367 }
00368
00369 int init_process_info_sysdep(void) {
00370
00371 register int pagesize;
00372 struct vmmeter vmm;
00373 int mib[2];
00374 size_t len;
00375
00376 struct nlist nlst [] = {
00377 { "_bufspace"},
00378 { "_cnt" },
00379 { 0 }
00380 };
00381
00382 if(getuid()!=0) {
00383
00384 return FALSE;
00385
00386 }
00387
00388 mib[0] = CTL_HW;
00389 mib[1] = HW_NCPU;
00390 len = sizeof(num_cpus);
00391 sysctl(mib, 2, &num_cpus, &len, NULL, 0);
00392
00393 kvm_handle = kvm_open(NULL, NULL, NULL, O_RDONLY, "monit");
00394
00395 if ( kvm_handle == NULL ) {
00396
00397 return FALSE;
00398
00399 }
00400
00401
00402
00403
00404
00405 if (kvm_nlist (kvm_handle, nlst) < 0)
00406 {
00407 return FALSE;
00408 }
00409
00410
00411
00412
00413 pagesize = getpagesize ();
00414 pageshift = 0;
00415 while (pagesize > 1) {
00416
00417 pageshift++;
00418 pagesize >>= 1;
00419
00420 }
00421
00422
00423 pageshift -= LOG1024;
00424
00425
00426 if (kvm_read (kvm_handle, nlst[1].n_value,
00427 &vmm, sizeof (vmm)) != sizeof (vmm)) {
00428 return FALSE;
00429
00430 }
00431
00432 mem_kbyte_max= vmm.v_pageout_free_min +
00433 vmm.v_free_count + vmm.v_wire_count +
00434 vmm.v_active_count + vmm.v_inactive_count;
00435
00436 return TRUE;
00437
00438 }
00439
00440 int get_process_info_sysdep(ProcInfo_T p) {
00441
00442 struct kinfo_proc *pinfo;
00443
00444
00445
00446 struct pstats pstats;
00447 struct plimit plimit;
00448 struct vmspace *vms;
00449 register struct rusage *rup;
00450 long stat_utime;
00451 long stat_stime;
00452 long stat_cutime;
00453 long stat_cstime;
00454
00455 u_int64_t rss_lim;
00456
00457 int count;
00458
00459
00460
00461 pinfo = kvm_getprocs(kvm_handle, KERN_PROC_PID, p->pid, &count);
00462
00463 if ((pinfo == NULL) || (count < 1)) {
00464
00465 return FALSE;
00466
00467 }
00468
00469
00470
00471
00472 if (kvm_read (kvm_handle,
00473 (unsigned long) pinfo [0].kp_proc.p_stats,
00474 &pstats, sizeof (pstats)) == sizeof (pstats)) {
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 rup = &pstats.p_ru;
00485 calcru(&(pinfo [0]).kp_proc,
00486 &rup->ru_utime, &rup->ru_stime, NULL);
00487
00488 stat_utime = tv2sec (pstats.p_ru.ru_utime);
00489 stat_stime = tv2sec (pstats.p_ru.ru_stime);
00490
00491 stat_cutime = tv2sec (pstats.p_cru.ru_utime);
00492 stat_cstime = tv2sec (pstats.p_cru.ru_stime);
00493
00494 } else {
00495
00496 return FALSE;
00497
00498 }
00499
00500 p->cputime_prev= p->cputime;
00501 p->cputime= (int)(( stat_utime + stat_stime ) / 1000);
00502
00503 if( include_children ) {
00504
00505 p->cputime+= (int)(( stat_cutime + stat_cstime ) / 1000);
00506
00507 }
00508
00509
00510
00511 if ( p->time_prev == 0.0 ) {
00512
00513 p->cputime_prev= p->cputime;
00514
00515 }
00516
00517
00518
00519
00520 if (kvm_read (kvm_handle,
00521 (unsigned long) pinfo [0].kp_proc.p_limit,
00522 (char *) &plimit, sizeof (plimit)) != sizeof (plimit)) {
00523
00524 return FALSE;
00525
00526 }
00527
00528 rss_lim = (u_int64_t)
00529 (plimit.pl_rlimit [RLIMIT_RSS].rlim_cur);
00530
00531 vms = &pinfo [0].kp_eproc.e_vm;
00532
00533 p->mem_kbyte= (u_int64_t) pagetok (vms->vm_rssize);
00534
00535
00536
00537
00538
00539 if ( pinfo [0].kp_proc.p_stat == SZOMB ) {
00540
00541 p->status_flag |= PROCESS_ZOMBIE;
00542
00543 }
00544
00545 p->mem_percent = (int) ((double) p->mem_kbyte * 1000.0 / mem_kbyte_max);
00546
00547 return TRUE;
00548
00549 }
00550
00551 #endif
00552
00553 #ifdef DARWIN
00554
00555 #define pagetok(size) ((size) << pageshift)
00556 #define tv2sec(tv) (((u_int64_t) tv.tv_sec * 1000000) + (u_int64_t) tv.tv_usec)
00557
00558 static int pageshift;
00559 static long mem_kbyte_max;
00560
00561 #ifndef LOG1024
00562 #define LOG1024 10
00563 #endif
00564
00565 static kvm_t * kvm_handle;
00566
00567 static void calcru(struct proc *p, struct timeval *up, struct timeval *sp,
00568 struct timeval *ip)
00569 {
00570 quad_t totusec;
00571 u_quad_t u, st, ut, it, tot;
00572 #if (__FreeBSD_version < 300003)
00573 long sec, usec;
00574 #endif
00575
00576 struct timeval tv;
00577
00578 st = p->p_sticks;
00579 ut = p->p_uticks;
00580 it = p->p_iticks;
00581
00582 tot = st + ut + it;
00583 if (tot == 0)
00584 {
00585 st = 1;
00586 tot = 1;
00587 }
00588
00589 #if (defined __FreeBSD__) && (__FreeBSD_version >= 300003)
00590 totusec = (u_quad_t) p->p_runtime;
00591 #else
00592 sec = p->p_rtime.tv_usec;
00593 usec = p->p_rtime.tv_usec;
00594
00595 totusec = (quad_t)sec * 1000000 + usec;
00596 #endif
00597
00598 if(totusec < 0)
00599 {
00600 fprintf (stderr, "calcru: negative time: %ld usec\n",
00601 (long)totusec);
00602 totusec = 0;
00603 }
00604
00605 u = totusec;
00606 st = (u * st) / tot;
00607 sp->tv_sec = st / 1000000;
00608 sp->tv_usec = st % 1000000;
00609 ut = (u * ut) / tot;
00610 up->tv_sec = ut / 1000000;
00611 up->tv_usec = ut % 1000000;
00612
00613 if(ip != NULL)
00614 {
00615 it = (u * it) / tot;
00616 ip->tv_sec = it / 1000000;
00617 ip->tv_usec = it % 1000000;
00618 }
00619 }
00620
00621 int init_process_info_sysdep(void) {
00622
00623 register int pagesize;
00624 struct vmmeter vmm;
00625
00626 struct nlist nlst [] = {
00627 { "_bufspace"},
00628 { "_cnt" },
00629 { 0 }
00630 };
00631
00632 if(getuid()!=0) {
00633
00634 return FALSE;
00635
00636 }
00637
00638 kvm_handle = kvm_open(NULL, NULL, NULL, O_RDONLY, "monit");
00639
00640 if ( kvm_handle == NULL ) {
00641
00642 return FALSE;
00643
00644 }
00645
00646
00647
00648
00649
00650 if (kvm_nlist (kvm_handle, nlst) < 0)
00651 {
00652 return FALSE;
00653 }
00654
00655
00656
00657
00658 pagesize = getpagesize ();
00659 pageshift = 0;
00660 while (pagesize > 1) {
00661
00662 pageshift++;
00663 pagesize >>= 1;
00664
00665 }
00666
00667
00668 pageshift -= LOG1024;
00669
00670
00671 if (kvm_read (kvm_handle, nlst[1].n_value,
00672 &vmm, sizeof (vmm)) != sizeof (vmm)) {
00673 return FALSE;
00674
00675 }
00676
00677 mem_kbyte_max= vmm.v_free_min +
00678 vmm.v_free_count + vmm.v_wire_count +
00679 vmm.v_active_count + vmm.v_inactive_count;
00680
00681 return TRUE;
00682
00683 }
00684
00685 int get_process_info_sysdep(ProcInfo_T p) {
00686
00687 struct kinfo_proc *pinfo;
00688 struct pstats pstats;
00689 struct plimit plimit;
00690 struct vmspace *vms;
00691 register struct rusage *rup;
00692 long stat_utime;
00693 long stat_stime;
00694 long stat_cutime;
00695 long stat_cstime;
00696
00697 u_int64_t rss_lim;
00698
00699 int count;
00700
00701
00702 return FALSE;
00703
00704
00705
00706 pinfo = kvm_getprocs(kvm_handle, KERN_PROC_PID, p->pid, &count);
00707
00708 if ((pinfo == NULL) || (count < 1)) {
00709
00710 return FALSE;
00711
00712 }
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738 p->cputime_prev= p->cputime;
00739 p->cputime= ( stat_utime + stat_stime );
00740
00741 if( include_children ) {
00742
00743 p->cputime+= ( stat_cutime + stat_cstime );
00744
00745 }
00746
00747
00748
00749 if ( p->time_prev == 0.0 ) {
00750
00751 p->cputime_prev= p->cputime;
00752
00753 }
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766 rss_lim = (u_int64_t)
00767 (plimit.pl_rlimit [RLIMIT_RSS].rlim_cur);
00768
00769 vms = &pinfo [0].kp_eproc.e_vm;
00770
00771 p->mem_kbyte= (u_int64_t) pagetok (vms->vm_rssize);
00772
00773
00774
00775
00776
00777 if ( pinfo [0].kp_proc.p_stat == SZOMB ) {
00778
00779 p->status_flag |= PROCESS_ZOMBIE;
00780
00781 }
00782
00783 p->mem_percent = (int) ((double) p->mem_kbyte * 1000.0 / mem_kbyte_max);
00784
00785 return TRUE;
00786
00787 }
00788
00789 #endif
00790