sysdep_DARWIN.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C), 2000-2003 by Contributors to the monit codebase. 
00003  * All Rights Reserved.
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License as
00007  * published by the Free Software Foundation; either version 2 of the
00008  * License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful, but
00011  * WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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 <machine/vmparam.h>
00064 #include <sys/vmmeter.h>
00065 #include <sys/sysctl.h>
00066 
00067 #include "process.h"
00068 #include "sysdep.h"
00069 
00082 #define pagetok(size) ((size) << pageshift)
00083 #define tv2sec(tv) (((u_int64_t) tv.tv_sec * 1000000) + (u_int64_t) tv.tv_usec)
00084 
00085 static int pageshift;
00086 static long mem_kbyte_max;
00087 
00088 #ifndef LOG1024
00089 #define LOG1024         10
00090 #endif
00091 
00092 static kvm_t * kvm_handle;
00093 
00094 static void calcru(struct proc *p, struct timeval *up, struct timeval *sp,
00095            struct timeval *ip)
00096 {
00097   quad_t totusec;
00098   u_quad_t u, st, ut, it, tot;
00099   #if (__FreeBSD_version < 300003)
00100   long sec, usec;
00101   #endif
00102   
00103   struct timeval tv;
00104 
00105   st = p->p_sticks;
00106   ut = p->p_uticks;
00107   it = p->p_iticks;
00108   
00109   tot = st + ut + it;
00110   if (tot == 0)
00111     {
00112       st = 1;
00113       tot = 1;
00114     }
00115   
00116   #if (defined __FreeBSD__) && (__FreeBSD_version >= 300003)
00117   totusec = (u_quad_t) p->p_runtime;
00118   #else
00119   sec = p->p_rtime.tv_usec;
00120   usec = p->p_rtime.tv_usec;
00121   
00122   totusec = (quad_t)sec * 1000000 + usec;
00123   #endif
00124   
00125   if(totusec < 0)
00126     {
00127       fprintf (stderr, "calcru: negative time: %ld usec\n",
00128            (long)totusec);
00129       totusec = 0;
00130     }
00131   
00132   u = totusec;
00133   st = (u * st) / tot;
00134   sp->tv_sec = st / 1000000;
00135   sp->tv_usec = st % 1000000;
00136   ut = (u * ut) / tot;
00137   up->tv_sec = ut / 1000000;
00138   up->tv_usec = ut % 1000000;
00139   
00140   if(ip != NULL)
00141     {
00142       it = (u * it) / tot;
00143       ip->tv_sec = it / 1000000;
00144       ip->tv_usec = it % 1000000;
00145     }
00146 }
00147 
00148 int init_process_info_sysdep(void) {
00149 
00150   register int pagesize;
00151   struct vmmeter vmm;
00152   
00153   struct nlist nlst [] = {
00154       { "_bufspace"},
00155       { "_cnt" },
00156       { 0 }
00157   };
00158 
00159   if(getuid()!=0) {
00160 
00161     return FALSE;
00162 
00163   }
00164 
00165   kvm_handle = kvm_open(NULL, NULL, NULL, O_RDONLY, "monit");
00166   
00167   if ( kvm_handle == NULL ) {
00168     
00169     return FALSE;
00170     
00171   }
00172   
00173   /* ----------------------------- INIT MEM -----------------------------*/
00174   /* Got it from libgtop/sysdep/freebsd/mem.c */
00175 
00176   /* Initialize nlist structure */
00177   if (kvm_nlist (kvm_handle, nlst) < 0)
00178   {
00179     return FALSE;
00180   }
00181 
00182   /* get the page size with "getpagesize" and calculate pageshift
00183    * from it */
00184 
00185   pagesize = getpagesize ();
00186   pageshift = 0;
00187   while (pagesize > 1) {
00188 
00189     pageshift++;
00190     pagesize >>= 1;
00191 
00192   }
00193 
00194   /* we only need the amount of log(2)1024 for our conversion */
00195   pageshift -= LOG1024;
00196 
00197   /* Get the data from kvm_* */
00198   if (kvm_read (kvm_handle, nlst[1].n_value,
00199         &vmm, sizeof (vmm)) != sizeof (vmm)) {
00200     return FALSE;
00201 
00202   }
00203 
00204   mem_kbyte_max= vmm.v_free_min +
00205     vmm.v_free_count + vmm.v_wire_count +
00206     vmm.v_active_count + vmm.v_inactive_count;
00207 
00208   return TRUE;
00209 
00210 }
00211 
00212 int get_process_info_sysdep(ProcInfo_T p) {
00213 
00214   struct kinfo_proc *pinfo;
00215   struct pstats pstats;
00216   struct plimit plimit;
00217   struct vmspace *vms;
00218   register struct rusage *rup;
00219   long stat_utime;
00220   long stat_stime;
00221   long stat_cutime;
00222   long stat_cstime;
00223 
00224   u_int64_t rss_lim;
00225 
00226   int count;
00227 
00228   /* Put this here until fixed */
00229   return FALSE;
00230 
00231   /* Got it from libgtop */
00232 
00233   pinfo = kvm_getprocs(kvm_handle, KERN_PROC_PID, p->pid, &count);
00234 
00235   if ((pinfo == NULL) || (count < 1)) {
00236 
00237     return FALSE;
00238 
00239   }
00240 
00241   /* ----------------------------- CPU TIMING ----------------------------*/
00242   /* Got it from libgtop/sysdep/freebsd/proctime.c */
00243   
00244   /*  if ((pinfo [0].kp_proc.p_flag & P_INMEM) &&
00245       kvm_read (kvm_handle, &(pinfo [0]).kp_proc,
00246          (unsigned long) &u_addr->u_stats,
00247          (char *) &pstats, sizeof (pstats)) == sizeof (pstats)) {
00248 
00249     rup = &pstats.p_ru;
00250     calcru(&(pinfo [0]).kp_proc,
00251        &rup->ru_utime, &rup->ru_stime, NULL);
00252 
00253     stat_utime = tv2sec (pstats.p_ru.ru_utime);
00254     stat_stime = tv2sec (pstats.p_ru.ru_stime);
00255 
00256     stat_cutime = tv2sec (pstats.p_cru.ru_utime);
00257     stat_cstime = tv2sec (pstats.p_cru.ru_stime);
00258 
00259   } else {
00260 
00261     return FALSE;
00262 
00263     } */
00264 
00265   p->cputime_prev= p->cputime;
00266   p->cputime= ( stat_utime + stat_stime );
00267 
00268   if( include_children ) {
00269 
00270     p->cputime+= ( stat_cutime + stat_cstime );
00271 
00272   }
00273 
00274   /* first run ? */
00275 
00276   if ( p->time_prev == 0.0 ) {
00277 
00278     p->cputime_prev= p->cputime;
00279 
00280   }
00281 
00282   /* ----------------------------- MEMORY --------------------------------*/
00283   /* Got it from libgtop/sysdep/freebsd/procmem.c */
00284 
00285   /*  if (kvm_read (kvm_handle,
00286         (unsigned long) pinfo [0].kp_proc.p_limit,
00287         (char *) &plimit, sizeof (plimit)) != sizeof (plimit)) {
00288 
00289     return FALSE;
00290 
00291   }
00292   */
00293   rss_lim = (u_int64_t)
00294     (plimit.pl_rlimit [RLIMIT_RSS].rlim_cur);
00295 
00296   vms = &pinfo [0].kp_eproc.e_vm;
00297 
00298   p->mem_kbyte= (u_int64_t) pagetok (vms->vm_rssize);
00299              /* <<LOG1024 removed, we wanna have kb */
00300 
00301   /* ----------------------------- STATE ---------------------------------*/
00302   /* Got it from libgtop/sysdep/freebsd/procstate.c */
00303 
00304   if ( pinfo [0].kp_proc.p_stat == SZOMB ) {
00305 
00306     p->status_flag |= PROCESS_ZOMBIE;
00307 
00308   }
00309 
00310   p->mem_percent = (int) ((double) p->mem_kbyte * 1000.0 / mem_kbyte_max);
00311 
00312   return TRUE;
00313 
00314 }