1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1989-2011 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Eclipse Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.eclipse.org/org/documents/epl-v10.html * 11 * (with md5 checksum b35adb5213ca9657e911e9befb180842) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <glenn.s.fowler@gmail.com> * 18 * * 19 ***********************************************************************/ 20 #pragma prototyped 21 /* 22 * Glenn Fowler 23 * AT&T Research 24 * 25 * process status stream PSS_METHOD_kvm implementation 26 */ 27 28 #include "psslib.h" 29 30 #if PSS_METHOD != PSS_METHOD_kvm 31 32 NoN(pss_kvm) 33 34 #else 35 36 #include <kvm.h> 37 #if _sys_time 38 #include <sys/time.h> 39 #endif 40 #if _sys_param 41 #include <sys/param.h> 42 #endif 43 #if _sys_proc 44 #include <sys/proc.h> 45 #endif 46 #if _sys_user 47 #include <sys/user.h> 48 #endif 49 #include <sys/sysctl.h> 50 #include <sys/tty.h> 51 52 #if !_mem_p_pid_extern_proc 53 #define extern_proc proc 54 #endif 55 56 #ifndef SIDL 57 #ifdef LSIDL 58 #define SIDL LSIDL 59 #else 60 #define SIDL 1 61 #endif 62 #endif 63 #ifndef SRUN 64 #ifdef LSRUN 65 #define SRUN LSRUN 66 #else 67 #define SRUN 2 68 #endif 69 #endif 70 #ifndef SSLEEP 71 #ifdef LSSLEEP 72 #define SSLEEP LSSLEEP 73 #else 74 #define SSLEEP 3 75 #endif 76 #endif 77 #ifndef SSTOP 78 #ifdef LSSTOP 79 #define SSTOP LSSTOP 80 #else 81 #define SSTOP 4 82 #endif 83 #endif 84 #ifndef SZOMB 85 #ifdef LSZOMB 86 #define SZOMB LSZOMB 87 #else 88 #define SZOMB 5 89 #endif 90 #endif 91 #ifndef SDEAD 92 #ifdef LSDEAD 93 #define SDEAD LSDEAD 94 #else 95 #define SDEAD 6 96 #endif 97 #endif 98 #ifndef SONPROC 99 #ifdef LSONPROC 100 #define SONPROC LSONPROC 101 #else 102 #define SONPROC 7 103 #endif 104 #endif 105 #ifndef SSUSPENDED 106 #ifdef LSSUSPENDED 107 #define SSUSPENDED LSSUSPENDED 108 #else 109 #define SSUSPENDED 8 110 #endif 111 #endif 112 113 typedef struct State_s 114 { 115 kvm_t* kd; 116 struct kinfo_proc* kp; 117 struct kinfo_proc* ke; 118 struct extern_proc* pr; 119 struct eproc* px; 120 } State_t; 121 122 static int 123 kvm_init(Pss_t* pss) 124 { 125 register State_t* state; 126 127 if (!(state = vmnewof(pss->vm, 0, State_t, 1, 0))) 128 { 129 if (pss->disc->errorf) 130 (*pss->disc->errorf)(pss, pss->disc, ERROR_SYSTEM|2, "out of space"); 131 return -1; 132 } 133 if (!(state->kd = kvm_open(NiL, NiL, 0, O_RDONLY, NiL))) 134 { 135 if (pss->disc->errorf) 136 (*pss->disc->errorf)(pss, pss->disc, ERROR_SYSTEM|1, "kvm open error"); 137 return -1; 138 } 139 pss->data = state; 140 error(1, "%s: pss method is currently incomplete", pss->meth->name); 141 return 1; 142 } 143 144 static int 145 kvm_done(Pss_t* pss) 146 { 147 register State_t* state = (State_t*)pss->data; 148 149 kvm_close(state->kd); 150 return 1; 151 } 152 153 static int 154 kvm_readf(Pss_t* pss, Pss_id_t pid) 155 { 156 register State_t* state = (State_t*)pss->data; 157 int count; 158 159 if (pid) 160 { 161 if (!(state->kp = kvm_getprocs(state->kd, KERN_PROC_PID, pid, &count))) 162 return -1; 163 state->ke = state->kp + count; 164 } 165 else if (!state->kp) 166 { 167 if (!(state->kp = kvm_getprocs(state->kd, KERN_PROC_ALL, 0, &count))) 168 return -1; 169 state->ke = state->kp + count; 170 } 171 if (state->kp >= state->ke) 172 return 0; 173 pss->pid = state->kp->kp_proc.p_pid; 174 state->pr = &state->kp->kp_proc; 175 state->px = &state->kp->kp_eproc; 176 state->kp++; 177 return 1; 178 } 179 180 static int 181 kvm_part(register Pss_t* pss, register Pssent_t* pe) 182 { 183 register State_t* state = (State_t*)pss->data; 184 185 pe->pid = state->pr->p_pid; 186 pe->pgrp = state->px->e_pgid; 187 pe->tty = state->px->e_tdev; 188 pe->uid = state->px->e_ucred.cr_uid; 189 #if 0 190 pe->sid = state->px->e_sess->s_sid; 191 #endif 192 switch (state->pr->p_stat) 193 { 194 case SIDL: pe->state = 'I'; break; 195 case SRUN: pe->state = 'R'; break; 196 case SSLEEP: pe->state = 'S'; break; 197 case SSTOP: pe->state = 'T'; break; 198 case SZOMB: pe->state = 'Z'; break; 199 default: pe->state = 'O'; break; 200 } 201 return 1; 202 } 203 204 static int 205 kvm_full(register Pss_t* pss, register Pssent_t* pe) 206 { 207 register State_t* state = (State_t*)pss->data; 208 unsigned long fields = pss->disc->fields & pss->meth->fields; 209 char* s; 210 int i; 211 212 if (pe->state != PSS_ZOMBIE) 213 { 214 if (fields & PSS_args) 215 { 216 s = state->pr->p_comm; 217 if (s[0] == '(' && s[i = strlen(s) - 1] == ')') 218 { 219 s[i] = 0; 220 s++; 221 } 222 pe->args = s; 223 } 224 if (fields & PSS_command) 225 { 226 s = state->pr->p_comm; 227 if (s[0] == '(' && s[i = strlen(s) - 1] == ')') 228 { 229 s[i] = 0; 230 s++; 231 } 232 pe->command = s; 233 } 234 } 235 #if _mem_p_addr_extern_proc 236 pe->addr = state->pr->p_addr; 237 #endif 238 #if _mem_p_wchan_extern_proc 239 pe->wchan = state->pr->p_wchan; 240 #endif 241 pe->flags = state->pr->p_flag; 242 pe->nice = state->pr->p_nice; 243 pe->ppid = state->px->e_ppid; 244 #if PSS_pri && _mem_p_usrpri_extern_proc 245 pe->pri = state->pr->p_usrpri; 246 #endif 247 #ifdef FWIDTH 248 pe->cpu = state->pr->p_pctcpu >> FWIDTH; 249 #endif 250 pe->refcount = state->px->e_xccount; 251 pe->rss = state->px->e_xrssize; 252 #if _mem_e_xsize_eproc 253 pe->size = state->px->e_xsize; 254 #else 255 pe->size = state->px->e_vm.vm_tsize + state->px->e_vm.vm_dsize + state->px->e_vm.vm_ssize; 256 #endif 257 #if _mem_p_starttime_extern_proc 258 pe->start = state->pr->p_starttime.tv_sec; 259 #endif 260 pe->time = state->pr->p_rtime.tv_sec; 261 return 1; 262 } 263 264 static Pssmeth_t kvm_method = 265 { 266 "kvm", 267 "[-version?@(#)$Id: pss kvm (AT&T Research) 2008-01-31 $\n]" 268 "[-author?Glenn Fowler <gsf@research.att.com>]", 269 PSS_all, 270 kvm_init, 271 kvm_readf, 272 kvm_part, 273 kvm_full, 274 0, 275 0, 276 0, 277 kvm_done 278 }; 279 280 Pssmeth_t* _pss_method = &kvm_method; 281 282 #endif 283