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 #include <kvm.h>
00057 #include <sys/param.h>
00058 #include <sys/proc.h>
00059 #include <sys/resource.h>
00060 #include <sys/resourcevar.h>
00061 #include <sys/lock.h>
00062 #include <sys/user.h>
00063 #include <vm/vm.h>
00064 #include <vm/vm_object.h>
00065 #include <vm/pmap.h>
00066 #include <machine/pmap.h>
00067 #include <machine/vmparam.h>
00068 #include <vm/vm_map.h>
00069 #include <sys/vmmeter.h>
00070 #include <sys/sysctl.h>
00071
00072 #include "process.h"
00073 #include "sysdep.h"
00074
00087 #define pagetok(size) ((size) << pageshift)
00088 #define tv2sec(tv) (((u_int64_t) tv.tv_sec * 1000000) + (u_int64_t) tv.tv_usec)
00089
00090 static int pageshift;
00091 static long mem_kbyte_max;
00092
00093 #ifndef LOG1024
00094 #define LOG1024 10
00095 #endif
00096
00097 static kvm_t * kvm_handle;
00098
00099 static void calcru(struct proc *p, struct timeval *up, struct timeval *sp,
00100 struct timeval *ip)
00101 {
00102 quad_t totusec;
00103 u_quad_t u, st, ut, it, tot;
00104 #if (__FreeBSD_version < 300003)
00105 long sec, usec;
00106 #endif
00107
00108 st = p->p_sticks;
00109 ut = p->p_uticks;
00110 it = p->p_iticks;
00111
00112 tot = st + ut + it;
00113 if (tot == 0)
00114 {
00115 st = 1;
00116 tot = 1;
00117 }
00118
00119 #if (defined __FreeBSD__) && (__FreeBSD_version >= 300003)
00120 totusec = (u_quad_t) p->p_runtime;
00121 #else
00122 sec = p->p_rtime.tv_usec;
00123 usec = p->p_rtime.tv_usec;
00124
00125 totusec = (quad_t)sec * 1000000 + usec;
00126 #endif
00127
00128 if(totusec < 0)
00129 {
00130 fprintf (stderr, "calcru: negative time: %ld usec\n",
00131 (long)totusec);
00132 totusec = 0;
00133 }
00134
00135 u = totusec;
00136 st = (u * st) / tot;
00137 sp->tv_sec = st / 1000000;
00138 sp->tv_usec = st % 1000000;
00139 ut = (u * ut) / tot;
00140 up->tv_sec = ut / 1000000;
00141 up->tv_usec = ut % 1000000;
00142
00143 if(ip != NULL)
00144 {
00145 it = (u * it) / tot;
00146 ip->tv_sec = it / 1000000;
00147 ip->tv_usec = it % 1000000;
00148 }
00149 }
00150
00151 int init_process_info_sysdep(void) {
00152
00153 register int pagesize;
00154 struct vmmeter vmm;
00155 int mib[2];
00156 size_t len;
00157
00158 struct nlist nlst [] = {
00159 { "_bufspace"},
00160 { "_cnt" },
00161 { 0 }
00162 };
00163
00164 if(getuid()!=0) {
00165
00166 return FALSE;
00167
00168 }
00169
00170 mib[0] = CTL_HW;
00171 mib[1] = HW_NCPU;
00172 len = sizeof(num_cpus);
00173 sysctl(mib, 2, &num_cpus, &len, NULL, 0);
00174
00175 kvm_handle = kvm_open(NULL, NULL, NULL, O_RDONLY, "monit");
00176
00177 if ( kvm_handle == NULL ) {
00178
00179 return FALSE;
00180
00181 }
00182
00183
00184
00185
00186
00187 if (kvm_nlist (kvm_handle, nlst) < 0)
00188 {
00189 return FALSE;
00190 }
00191
00192
00193
00194
00195 pagesize = getpagesize ();
00196 pageshift = 0;
00197 while (pagesize > 1) {
00198
00199 pageshift++;
00200 pagesize >>= 1;
00201
00202 }
00203
00204
00205 pageshift -= LOG1024;
00206
00207
00208 if (kvm_read (kvm_handle, nlst[1].n_value,
00209 &vmm, sizeof (vmm)) != sizeof (vmm)) {
00210 return FALSE;
00211
00212 }
00213
00214 mem_kbyte_max= vmm.v_pageout_free_min +
00215 vmm.v_free_count + vmm.v_wire_count +
00216 vmm.v_active_count + vmm.v_inactive_count;
00217
00218 return TRUE;
00219
00220 }
00221
00222 int get_process_info_sysdep(ProcInfo_T p) {
00223
00224 struct kinfo_proc *pinfo;
00225
00226
00227
00228 struct pstats pstats;
00229 struct plimit plimit;
00230 struct vmspace *vms;
00231 register struct rusage *rup;
00232 long stat_utime;
00233 long stat_stime;
00234 long stat_cutime;
00235 long stat_cstime;
00236
00237 u_int64_t rss_lim;
00238
00239 int count;
00240
00241
00242
00243 pinfo = kvm_getprocs(kvm_handle, KERN_PROC_PID, p->pid, &count);
00244
00245 if ((pinfo == NULL) || (count < 1)) {
00246
00247 return FALSE;
00248
00249 }
00250
00251
00252
00253
00254 if (kvm_read (kvm_handle,
00255 (unsigned long) pinfo [0].kp_proc.p_stats,
00256 &pstats, sizeof (pstats)) == sizeof (pstats)) {
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 rup = &pstats.p_ru;
00267 calcru(&(pinfo [0]).kp_proc,
00268 &rup->ru_utime, &rup->ru_stime, NULL);
00269
00270 stat_utime = tv2sec (pstats.p_ru.ru_utime);
00271 stat_stime = tv2sec (pstats.p_ru.ru_stime);
00272
00273 stat_cutime = tv2sec (pstats.p_cru.ru_utime);
00274 stat_cstime = tv2sec (pstats.p_cru.ru_stime);
00275
00276 } else {
00277
00278 return FALSE;
00279
00280 }
00281
00282 p->cputime_prev= p->cputime;
00283 p->cputime= (int)(( stat_utime + stat_stime ) / 1000);
00284
00285 if( include_children ) {
00286
00287 p->cputime+= (int)(( stat_cutime + stat_cstime ) / 1000);
00288
00289 }
00290
00291
00292
00293 if ( p->time_prev == 0.0 ) {
00294
00295 p->cputime_prev= p->cputime;
00296
00297 }
00298
00299
00300
00301
00302 if (kvm_read (kvm_handle,
00303 (unsigned long) pinfo [0].kp_proc.p_limit,
00304 (char *) &plimit, sizeof (plimit)) != sizeof (plimit)) {
00305
00306 return FALSE;
00307
00308 }
00309
00310 rss_lim = (u_int64_t)
00311 (plimit.pl_rlimit [RLIMIT_RSS].rlim_cur);
00312
00313 vms = &pinfo [0].kp_eproc.e_vm;
00314
00315 p->mem_kbyte= (u_int64_t) pagetok (vms->vm_rssize);
00316
00317
00318
00319
00320
00321 if ( pinfo [0].kp_proc.p_stat == SZOMB ) {
00322
00323 p->status_flag |= PROCESS_ZOMBIE;
00324
00325 }
00326
00327 p->mem_percent = (int) ((double) p->mem_kbyte * 1000.0 / mem_kbyte_max);
00328
00329 return TRUE;
00330
00331 }