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 #ifdef HAVE_SYS_STAT_H
00028 #include <sys/stat.h>
00029 #endif
00030
00031 #ifdef HAVE_FCNTL_H
00032 #include <fcntl.h>
00033 #endif
00034
00035 #ifdef HAVE_STDLIB_H
00036 #include <stdlib.h>
00037 #endif
00038
00039 #ifdef TIME_WITH_SYS_TIME
00040 #include <time.h>
00041
00042 #ifdef HAVE_SYS_TIME_H
00043 #include <sys/time.h>
00044 #endif
00045 #else
00046 #include <time.h>
00047 #endif
00048
00049 #ifdef HAVE_STRING_H
00050 #include <string.h>
00051 #endif
00052
00053 #include <stdio.h>
00054
00055
00056 #ifdef SOLARIS
00057 #include <procfs.h>
00058 #endif
00059
00060 #ifdef FREEBSD
00061 #include <kvm.h>
00062 #include <sys/param.h>
00063 #include <sys/proc.h>
00064 #include <sys/resource.h>
00065 #include <sys/resourcevar.h>
00066 #include <sys/lock.h>
00067 #include <sys/user.h>
00068 #include <vm/vm.h>
00069 #include <vm/vm_object.h>
00070 #include <vm/pmap.h>
00071 #include <machine/pmap.h>
00072 #include <machine/vmparam.h>
00073 #include <vm/vm_map.h>
00074 #include <sys/vmmeter.h>
00075 #include <sys/sysctl.h>
00076 #endif
00077
00078 #ifdef LINUX
00079 #include <asm/param.h>
00080 #include <asm/page.h>
00081 #endif
00082
00083
00084 #include "process.h"
00085
00097
00098
00099 #ifdef SOLARIS
00100
00101 int init_process_info_sysdep(void) {
00102
00103 return (getuid()==0);
00104
00105 }
00106
00107 double timestruc_to_tseconds(timestruc_t t) {
00108 return t.tv_sec * 10 + t.tv_nsec / 100000000.0;
00109 }
00110
00111 int get_process_info_sysdep(ProcInfo_T p) {
00112
00113 char buf[4096];
00114 psinfo_t * psinfo= (psinfo_t *)&buf;
00115 pstatus_t * pstatus= (pstatus_t *)&buf;
00116
00117 if (!read_proc_file(buf,4096, "psinfo", p->pid)) {
00118
00119 return FALSE;
00120
00121 }
00122
00123
00124
00125
00126 if ( psinfo->pr_nlwp == 0 ) {
00127
00128 p->status_flag = PROCESS_ZOMBIE;
00129
00130 }
00131
00132
00133 if ( p->status_flag != PROCESS_ZOMBIE ) {
00134
00135
00136
00137 p->mem_percent = psinfo->pr_pctmem * 1000 / 0x8000;
00138 p->mem_kbyte = psinfo->pr_rssize;
00139
00140 if (!read_proc_file(buf,4096, "status", p->pid)) {
00141
00142 return FALSE;
00143
00144 }
00145
00146 p->cputime_prev= p->cputime;
00147 p->cputime= ( timestruc_to_tseconds(pstatus->pr_utime) +
00148 timestruc_to_tseconds(pstatus->pr_stime) );
00149
00150 if( include_children ) {
00151
00152 p->cputime+= ( timestruc_to_tseconds(pstatus->pr_cutime) +
00153 timestruc_to_tseconds(pstatus->pr_cstime) );
00154
00155 }
00156
00157
00158 if ( p->time_prev == 0.0 ) {
00159
00160 p->cputime_prev= p->cputime;
00161
00162 }
00163
00164 } else {
00165
00166 p->cputime_prev= p->cputime = 0;
00167 p->mem_kbyte= 0;
00168 p->mem_percent= 0.0;
00169
00170 }
00171
00172 return TRUE;
00173 }
00174
00175 #endif
00176
00177 #ifdef LINUX
00178
00179 #define PAGE_TO_KBYTE_SHIFT PAGE_SHIFT-10
00180
00181 static long mem_kbyte_max;
00182
00183 int init_process_info_sysdep(void) {
00184
00185 struct stat buf;
00186
00187
00188
00189 if ( stat("/proc/kcore", &buf) != 0 ) {
00190
00191 return FALSE;
00192
00193 }
00194
00195 mem_kbyte_max = buf.st_size>>10;
00196
00197 return TRUE;
00198
00199 }
00200
00201 int get_process_info_sysdep(ProcInfo_T p) {
00202
00203 char buf[4096];
00204 char* tmp;
00205 char stat_item_state;
00206 unsigned long stat_item_utime;
00207 unsigned long stat_item_stime;
00208 long stat_item_cutime;
00209 long stat_item_cstime;
00210 long stat_item_rss;
00211
00212 if (!read_proc_file(buf,4096, "stat", p->pid)) {
00213
00214 return FALSE;
00215
00216 }
00217
00218
00219
00220 tmp = strrchr(buf, ')') + 2;
00221
00222
00223
00224
00225 sscanf(tmp,"%c %*d %*d %*d %*d %*d %*u %*u"
00226 "%*u %*u %*u %lu %lu %ld %ld %*d %*d %*d "
00227 "%*d %*u %*u %ld %*u %*u %*u %*u %*u "
00228 "%*u %*u %*u %*u %*u %*u %*u %*u %*d %*d\n",
00229 &stat_item_state, &stat_item_utime, &stat_item_stime,
00230 &stat_item_cutime, &stat_item_cstime, &stat_item_rss);
00231
00232
00233
00234
00235 if ( PAGE_TO_KBYTE_SHIFT < 0 ) {
00236
00237 p->mem_kbyte= stat_item_rss >> abs(PAGE_TO_KBYTE_SHIFT);
00238
00239 } else {
00240
00241 p->mem_kbyte= stat_item_rss << abs(PAGE_TO_KBYTE_SHIFT);
00242
00243 }
00244
00245 p->mem_percent = (int) ((double) p->mem_kbyte * 1000.0 / mem_kbyte_max);
00246
00247
00248
00249
00250
00251 p->cputime_prev = p->cputime;
00252 p->cputime = ( stat_item_utime + stat_item_stime ) * 10 / HZ;
00253
00254 if ( include_children ) {
00255
00256 p->cputime += ( stat_item_cutime + stat_item_cstime ) * 10 / HZ;
00257
00258 }
00259
00260
00261
00262 if ( p->time_prev == 0.0 ) {
00263
00264 p->cputime_prev = p->cputime;
00265
00266 }
00267
00268
00269
00270 if ( stat_item_state == 'Z' ) {
00271
00272 p->status_flag |= PROCESS_ZOMBIE;
00273
00274 }
00275
00276 return TRUE;
00277
00278 }
00279
00280 #endif
00281
00282 #ifdef FREEBSD
00283
00284 #define pagetok(size) ((size) << pageshift)
00285 #define tv2sec(tv) (((u_int64_t) tv.tv_sec * 1000000) + (u_int64_t) tv.tv_usec)
00286
00287 static int pageshift;
00288 static long mem_kbyte_max;
00289
00290 #ifndef LOG1024
00291 #define LOG1024 10
00292 #endif
00293
00294 static kvm_t * kvm_handle;
00295
00296 static void calcru(struct proc *p, struct timeval *up, struct timeval *sp,
00297 struct timeval *ip)
00298 {
00299 quad_t totusec;
00300 u_quad_t u, st, ut, it, tot;
00301 #if (__FreeBSD_version < 300003)
00302 long sec, usec;
00303 #endif
00304
00305 st = p->p_sticks;
00306 ut = p->p_uticks;
00307 it = p->p_iticks;
00308
00309 tot = st + ut + it;
00310 if (tot == 0)
00311 {
00312 st = 1;
00313 tot = 1;
00314 }
00315
00316 #if (defined __FreeBSD__) && (__FreeBSD_version >= 300003)
00317 totusec = (u_quad_t) p->p_runtime;
00318 #else
00319 sec = p->p_rtime.tv_usec;
00320 usec = p->p_rtime.tv_usec;
00321
00322 totusec = (quad_t)sec * 1000000 + usec;
00323 #endif
00324
00325 if(totusec < 0)
00326 {
00327 fprintf (stderr, "calcru: negative time: %ld usec\n",
00328 (long)totusec);
00329 totusec = 0;
00330 }
00331
00332 u = totusec;
00333 st = (u * st) / tot;
00334 sp->tv_sec = st / 1000000;
00335 sp->tv_usec = st % 1000000;
00336 ut = (u * ut) / tot;
00337 up->tv_sec = ut / 1000000;
00338 up->tv_usec = ut % 1000000;
00339
00340 if(ip != NULL)
00341 {
00342 it = (u * it) / tot;
00343 ip->tv_sec = it / 1000000;
00344 ip->tv_usec = it % 1000000;
00345 }
00346 }
00347
00348 int init_process_info_sysdep(void) {
00349
00350 register int pagesize;
00351 struct vmmeter vmm;
00352
00353 struct nlist nlst [] = {
00354 { "_bufspace"},
00355 { "_cnt" },
00356 { 0 }
00357 };
00358
00359 if(getuid()!=0) {
00360
00361 return FALSE;
00362
00363 }
00364
00365 kvm_handle = kvm_open(NULL, NULL, NULL, O_RDONLY, "monit");
00366
00367 if ( kvm_handle == NULL ) {
00368
00369 return FALSE;
00370
00371 }
00372
00373
00374
00375
00376
00377 if (kvm_nlist (kvm_handle, nlst) < 0)
00378 {
00379 return FALSE;
00380 }
00381
00382
00383
00384
00385 pagesize = getpagesize ();
00386 pageshift = 0;
00387 while (pagesize > 1) {
00388
00389 pageshift++;
00390 pagesize >>= 1;
00391
00392 }
00393
00394
00395 pageshift -= LOG1024;
00396
00397
00398 if (kvm_read (kvm_handle, nlst[1].n_value,
00399 &vmm, sizeof (vmm)) != sizeof (vmm)) {
00400 return FALSE;
00401
00402 }
00403
00404 mem_kbyte_max= vmm.v_pageout_free_min +
00405 vmm.v_free_count + vmm.v_wire_count +
00406 vmm.v_active_count + vmm.v_inactive_count;
00407
00408 return TRUE;
00409
00410 }
00411
00412 int get_process_info_sysdep(ProcInfo_T p) {
00413
00414 struct kinfo_proc *pinfo;
00415 struct user *u_addr = (struct user *)USRSTACK;
00416 struct pstats pstats;
00417 struct plimit plimit;
00418 struct vmspace *vms;
00419 register struct rusage *rup;
00420 long stat_utime;
00421 long stat_stime;
00422 long stat_cutime;
00423 long stat_cstime;
00424
00425 u_int64_t rss_lim;
00426
00427 int count;
00428
00429
00430
00431 pinfo = kvm_getprocs(kvm_handle, KERN_PROC_PID, p->pid, &count);
00432
00433 if ((pinfo == NULL) || (count < 1)) {
00434
00435 return FALSE;
00436
00437 }
00438
00439
00440
00441
00442 if ((pinfo [0].kp_proc.p_flag & P_INMEM) &&
00443 kvm_uread (kvm_handle, &(pinfo [0]).kp_proc,
00444 (unsigned long) &u_addr->u_stats,
00445 (char *) &pstats, sizeof (pstats)) == sizeof (pstats)) {
00446
00447 rup = &pstats.p_ru;
00448 calcru(&(pinfo [0]).kp_proc,
00449 &rup->ru_utime, &rup->ru_stime, NULL);
00450
00451 stat_utime = tv2sec (pstats.p_ru.ru_utime);
00452 stat_stime = tv2sec (pstats.p_ru.ru_stime);
00453
00454 stat_cutime = tv2sec (pstats.p_cru.ru_utime);
00455 stat_cstime = tv2sec (pstats.p_cru.ru_stime);
00456
00457 } else {
00458
00459 return FALSE;
00460
00461 }
00462
00463 p->cputime_prev= p->cputime;
00464 p->cputime= ( stat_utime + stat_stime );
00465
00466 if( include_children ) {
00467
00468 p->cputime+= ( stat_cutime + stat_cstime );
00469
00470 }
00471
00472
00473
00474 if ( p->time_prev == 0.0 ) {
00475
00476 p->cputime_prev= p->cputime;
00477
00478 }
00479
00480
00481
00482
00483 if (kvm_read (kvm_handle,
00484 (unsigned long) pinfo [0].kp_proc.p_limit,
00485 (char *) &plimit, sizeof (plimit)) != sizeof (plimit)) {
00486
00487 return FALSE;
00488
00489 }
00490
00491 rss_lim = (u_int64_t)
00492 (plimit.pl_rlimit [RLIMIT_RSS].rlim_cur);
00493
00494 vms = &pinfo [0].kp_eproc.e_vm;
00495
00496 p->mem_kbyte= (u_int64_t) pagetok (vms->vm_rssize);
00497
00498
00499
00500
00501
00502 if ( pinfo [0].kp_proc.p_stat == SZOMB ) {
00503
00504 p->status_flag |= PROCESS_ZOMBIE;
00505
00506 }
00507
00508 p->mem_percent = (int) ((double) p->mem_kbyte * 1000.0 / mem_kbyte_max);
00509
00510 return TRUE;
00511
00512 }
00513
00514 #endif
00515