00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00028 #include <stdio.h>
00029 #include <string.h>
00030 #include <stdlib.h>
00031 #include <unistd.h>
00032
00033 #include "../../dprint.h"
00034 #include "../../ut.h"
00035 #include "../../pt.h"
00036 #include "../../events.h"
00037 #include "../../mem/mem.h"
00038 #include "../../mem/shm_mem.h"
00039 #include "../../rpc.h"
00040 #include "../../rpc_lookup.h"
00041
00042
00046 typedef struct pkg_proc_stats {
00047 int rank;
00048 unsigned int pid;
00049 unsigned int used;
00050 unsigned int available;
00051 unsigned int real_used;
00052 } pkg_proc_stats_t;
00053
00057 static pkg_proc_stats_t *_pkg_proc_stats_list = NULL;
00058
00062 static int _pkg_proc_stats_no = 0;
00063
00067 int pkg_proc_stats_init(void)
00068 {
00069 _pkg_proc_stats_no = get_max_procs();
00070
00071 if(_pkg_proc_stats_no<=0)
00072 return -1;
00073 if(_pkg_proc_stats_list!=NULL)
00074 return -1;
00075 _pkg_proc_stats_list = (pkg_proc_stats_t*)shm_malloc(
00076 _pkg_proc_stats_no*sizeof(pkg_proc_stats_t));
00077 if(_pkg_proc_stats_list==NULL)
00078 return -1;
00079 memset(_pkg_proc_stats_list, 0,
00080 _pkg_proc_stats_no*sizeof(pkg_proc_stats_t));
00081 return 0;
00082 }
00083
00087 int pkg_proc_stats_myinit(int rank)
00088 {
00089 struct mem_info info;
00090 if(_pkg_proc_stats_list==NULL)
00091 return -1;
00092 if(process_no>=_pkg_proc_stats_no)
00093 return -1;
00094 _pkg_proc_stats_list[process_no].pid = (unsigned int)my_pid();
00095 _pkg_proc_stats_list[process_no].rank = rank;
00096
00097
00098 pkg_info(&info);
00099 _pkg_proc_stats_list[process_no].used = info.used;
00100 _pkg_proc_stats_list[process_no].real_used = info.real_used;
00101 return 0;
00102 }
00103
00107 int pkg_proc_stats_destroy(void)
00108 {
00109 if(_pkg_proc_stats_list==NULL)
00110 return -1;
00111 shm_free(_pkg_proc_stats_list);
00112 _pkg_proc_stats_list = 0;
00113 _pkg_proc_stats_no = 0;
00114 return 0;
00115 }
00116
00117
00121 static int pkg_proc_update_used(void *data)
00122 {
00123 if(_pkg_proc_stats_list==NULL)
00124 return -1;
00125 if(process_no>=_pkg_proc_stats_no)
00126 return -1;
00127 _pkg_proc_stats_list[process_no].used = (unsigned int)(long)data;
00128 return 0;
00129 }
00130
00134 static int pkg_proc_update_real_used(void *data)
00135 {
00136 if(_pkg_proc_stats_list==NULL)
00137 return -1;
00138 if(process_no>=_pkg_proc_stats_no)
00139 return -1;
00140 _pkg_proc_stats_list[process_no].real_used = (unsigned int)(long)data;
00141 _pkg_proc_stats_list[process_no].available = pkg_available();
00142 return 0;
00143 }
00144
00148 int register_pkg_proc_stats(void)
00149 {
00150 sr_event_register_cb(SREV_PKG_SET_USED, pkg_proc_update_used);
00151 sr_event_register_cb(SREV_PKG_SET_REAL_USED, pkg_proc_update_real_used);
00152 return 0;
00153 }
00154
00158 static const char* rpc_pkg_stats_doc[2] = {
00159 "Private memory (pkg) statistics per process",
00160 0
00161 };
00162
00166 int pkg_proc_get_pid_index(unsigned int pid)
00167 {
00168 int i;
00169 for(i=0; i<_pkg_proc_stats_no; i++)
00170 {
00171 if(_pkg_proc_stats_list[i].pid == pid)
00172 return i;
00173 }
00174 return -1;
00175 }
00176
00180 static void rpc_pkg_stats(rpc_t* rpc, void* ctx)
00181 {
00182 int i;
00183 int limit;
00184 int cval;
00185 str cname;
00186 void* th;
00187 int mode;
00188
00189 if(_pkg_proc_stats_list==NULL)
00190 {
00191 rpc->fault(ctx, 500, "Not initialized");
00192 return;
00193 }
00194 i = 0;
00195 mode = 0;
00196 cval = 0;
00197 limit = _pkg_proc_stats_no;
00198 if (rpc->scan(ctx, "*S", &cname) == 1)
00199 {
00200 if(cname.len==3 && strncmp(cname.s, "pid", 3)==0)
00201 mode = 1;
00202 else if(cname.len==4 && strncmp(cname.s, "rank", 4)==0)
00203 mode = 2;
00204 else if(cname.len==5 && strncmp(cname.s, "index", 5)==0)
00205 mode = 3;
00206 else {
00207 rpc->fault(ctx, 500, "Invalid filter type");
00208 return;
00209 }
00210
00211 if (rpc->scan(ctx, "d", &cval) < 1)
00212 {
00213 rpc->fault(ctx, 500, "One more parameter expected");
00214 return;
00215 }
00216 if(mode==1)
00217 {
00218 i = pkg_proc_get_pid_index((unsigned int)cval);
00219 if(i<0)
00220 {
00221 rpc->fault(ctx, 500, "No such pid");
00222 return;
00223 }
00224 limit = i + 1;
00225 } else if(mode==3) {
00226 i=cval;
00227 limit = i + 1;
00228 }
00229 }
00230
00231 for(; i<limit; i++)
00232 {
00233
00234 if(mode!=2 || _pkg_proc_stats_list[i].rank==cval)
00235 {
00236 if (rpc->add(ctx, "{", &th) < 0)
00237 {
00238 rpc->fault(ctx, 500, "Internal error creating rpc");
00239 return;
00240 }
00241 if(rpc->struct_add(th, "dddddd",
00242 "entry", i,
00243 "pid", _pkg_proc_stats_list[i].pid,
00244 "rank", _pkg_proc_stats_list[i].rank,
00245 "used", _pkg_proc_stats_list[i].used,
00246 "free", _pkg_proc_stats_list[i].available,
00247 "real_used", _pkg_proc_stats_list[i].real_used
00248 )<0)
00249 {
00250 rpc->fault(ctx, 500, "Internal error creating rpc");
00251 return;
00252 }
00253 }
00254 }
00255 }
00256
00260 rpc_export_t kex_pkg_rpc[] = {
00261 {"pkg.stats", rpc_pkg_stats, rpc_pkg_stats_doc, 0},
00262 {0, 0, 0, 0}
00263 };
00264
00268 int pkg_proc_stats_init_rpc(void)
00269 {
00270 if (rpc_register_array(kex_pkg_rpc)!=0)
00271 {
00272 LM_ERR("failed to register RPC commands\n");
00273 return -1;
00274 }
00275 return 0;
00276 }
00277