Skip to content

Commit ed9843e

Browse files
committed
Proper handling of per-proc stats during forking/ripping.
Attach all load & pkmem stats to the process slot, so we can hide and unhide them when the process is fork or terminated.
1 parent 3524c00 commit ed9843e

File tree

6 files changed

+134
-77
lines changed

6 files changed

+134
-77
lines changed

core_stats.c

+33-8
Original file line numberDiff line numberDiff line change
@@ -179,26 +179,27 @@ static unsigned long get_pkg_fragments( void*proc_id)
179179
}
180180

181181

182-
int init_pkg_stats(int no_procs)
182+
int init_pkg_stats(int procs_no)
183183
{
184184
unsigned short n;
185185
str n_str;
186186
char *name;
187+
str sname;
187188

188-
LM_DBG("setting stats for %d processes\n",no_procs);
189+
LM_DBG("setting stats for %d processes\n",procs_no);
189190

190-
pkg_status = shm_malloc(no_procs*sizeof(pkg_status_holder));
191-
marker_t = shm_malloc(no_procs*sizeof(time_t));
191+
pkg_status = shm_malloc(procs_no*sizeof(pkg_status_holder));
192+
marker_t = shm_malloc(procs_no*sizeof(time_t));
192193
if (pkg_status==NULL || marker_t==NULL) {
193194
LM_ERR("no more pkg mem for stats\n");
194195
return -1;
195196
}
196-
memset( pkg_status, 0, no_procs*sizeof(pkg_status_holder));
197-
memset( marker_t, 0, no_procs*sizeof(time_t));
198-
no_pkg_status = no_procs;
197+
memset( pkg_status, 0, procs_no*sizeof(pkg_status_holder));
198+
memset( marker_t, 0, procs_no*sizeof(time_t));
199+
no_pkg_status = procs_no;
199200

200201
/* build the stats and register them */
201-
for( n=0 ; n<no_procs ; n++) {
202+
for( n=0 ; n<procs_no ; n++) {
202203
n_str.s = int2str( n, &n_str.len);
203204

204205
if ( (name=build_stat_name( &n_str,"total_size"))==0 ||
@@ -207,41 +208,65 @@ int init_pkg_stats(int no_procs)
207208
LM_ERR("failed to add stat variable\n");
208209
return -1;
209210
}
211+
sname.s = name;
212+
sname.len = strlen(name);
213+
pt[n].pkg_total = get_stat(&sname);
214+
pt[n].pkg_total->flags |= STAT_HIDDEN;
210215

211216
if ( (name=build_stat_name( &n_str,"used_size"))==0 ||
212217
register_stat2("pkmem", name, (stat_var**)get_pkg_used_size,
213218
STAT_NO_RESET|STAT_SHM_NAME|STAT_IS_FUNC, (void*)(long)n, 0)!=0 ) {
214219
LM_ERR("failed to add stat variable\n");
215220
return -1;
216221
}
222+
sname.s = name;
223+
sname.len = strlen(name);
224+
pt[n].pkg_used = get_stat(&sname);
225+
pt[n].pkg_used->flags |= STAT_HIDDEN;
217226

218227
if ( (name=build_stat_name( &n_str,"real_used_size"))==0 ||
219228
register_stat2("pkmem", name, (stat_var**)get_pkg_real_used_size,
220229
STAT_NO_RESET|STAT_SHM_NAME|STAT_IS_FUNC, (void*)(long)n, 0)!=0 ) {
221230
LM_ERR("failed to add stat variable\n");
222231
return -1;
223232
}
233+
sname.s = name;
234+
sname.len = strlen(name);
235+
pt[n].pkg_rused = get_stat(&sname);
236+
pt[n].pkg_rused->flags |= STAT_HIDDEN;
224237

225238
if ( (name=build_stat_name( &n_str,"max_used_size"))==0 ||
226239
register_stat2("pkmem", name, (stat_var**)get_pkg_max_used_size,
227240
STAT_NO_RESET|STAT_SHM_NAME|STAT_IS_FUNC, (void*)(long)n, 0)!=0 ) {
228241
LM_ERR("failed to add stat variable\n");
229242
return -1;
230243
}
244+
sname.s = name;
245+
sname.len = strlen(name);
246+
pt[n].pkg_mused = get_stat(&sname);
247+
pt[n].pkg_mused->flags |= STAT_HIDDEN;
231248

232249
if ( (name=build_stat_name( &n_str,"free_size"))==0 ||
233250
register_stat2("pkmem", name, (stat_var**)get_pkg_free_size,
234251
STAT_NO_RESET|STAT_SHM_NAME|STAT_IS_FUNC, (void*)(long)n, 0)!=0 ) {
235252
LM_ERR("failed to add stat variable\n");
236253
return -1;
237254
}
255+
sname.s = name;
256+
sname.len = strlen(name);
257+
pt[n].pkg_free = get_stat(&sname);
258+
pt[n].pkg_free->flags |= STAT_HIDDEN;
238259

239260
if ( (name=build_stat_name( &n_str,"fragments"))==0 ||
240261
register_stat2("pkmem", name, (stat_var**)get_pkg_fragments,
241262
STAT_NO_RESET|STAT_SHM_NAME|STAT_IS_FUNC, (void*)(long)n, 0)!=0 ) {
242263
LM_ERR("failed to add stat variable\n");
243264
return -1;
244265
}
266+
sname.s = name;
267+
sname.len = strlen(name);
268+
pt[n].pkg_frags = get_stat(&sname);
269+
pt[n].pkg_frags->flags |= STAT_HIDDEN;
245270

246271
}
247272

main.c

-8
Original file line numberDiff line numberDiff line change
@@ -1388,14 +1388,6 @@ int main(int argc, char** argv)
13881388
goto error;
13891389
}
13901390

1391-
#ifdef PKG_MALLOC
1392-
/* init stats support for pkg mem */
1393-
if (init_pkg_stats(counted_max_processes)!=0) {
1394-
LM_ERR("failed to init stats for pkg\n");
1395-
goto error;
1396-
}
1397-
#endif
1398-
13991391
/* init avps */
14001392
if (init_extra_avps() != 0) {
14011393
LM_ERR("error while initializing avps\n");

pt.c

+41-18
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "bin_interface.h"
3636
#include "ipc.h"
3737
#include "daemonize.h"
38+
#include "core_stats.h"
3839

3940

4041
/* array with children pids, 0= main proc,
@@ -90,12 +91,19 @@ int init_multi_proc_support(void)
9091
memset(pt, 0, sizeof(struct process_table)*counted_max_processes);
9192

9293
for( i=0 ; i<counted_max_processes ; i++ ) {
94+
/* reset fds to prevent bogus ops */
9395
pt[i].unix_sock = -1;
9496
pt[i].idx = -1;
9597
pt[i].pid = -1;
9698
pt[i].ipc_pipe[0] = pt[i].ipc_pipe[1] = -1;
9799
}
98100

101+
/* create the load-related stats (initially marked as hidden */
102+
/* until the proc starts) */
103+
if (register_processes_load_stats( counted_max_processes ) != 0) {
104+
LM_ERR("failed to create load stats\n");
105+
return -1;
106+
}
99107

100108
/* create the IPC pipes for all possible procs */
101109
if (create_ipc_pipes( counted_max_processes )<0) {
@@ -109,6 +117,14 @@ int init_multi_proc_support(void)
109117
return -1;
110118
}
111119

120+
/* create the pkg_mem stats */
121+
#ifdef PKG_MALLOC
122+
if (init_pkg_stats(counted_max_processes)!=0) {
123+
LM_ERR("failed to init stats for pkg\n");
124+
return -1;
125+
}
126+
#endif
127+
112128
/* set the pid for the starter process */
113129
set_proc_attrs("starter");
114130
pt[process_no].flags = OSS_PROC_IS_RUNNING;
@@ -169,16 +185,6 @@ void set_proc_attrs( char *fmt, ...)
169185
}
170186

171187

172-
static int register_process_stats(int process_no)
173-
{
174-
if (register_process_load_stats(process_no) != 0) {
175-
LM_ERR("failed to create load stats\n");
176-
return -1;
177-
}
178-
179-
return 0;
180-
}
181-
182188
/* Resets all the values in the process table for a given id (a slot) so that
183189
* it can be reused later
184190
* WARNING: this should be called only by main process and when it is 100%
@@ -205,8 +211,19 @@ static void _reset_process_slot( int p_id )
205211
pt[p_id].log_level = pt[p_id].default_log_level = 0; /*not really needed*/
206212

207213
/* purge all load-related data */
208-
memset( &pt[p_id].load, 0, sizeof(struct proc_load));
209-
// FIXME ^^^ we need to remove the stat_vars also !!!!
214+
memset( &pt[p_id].load, 0, sizeof(struct proc_load_info));
215+
/* hide the load stats */
216+
pt[p_id].load_rt->flags |= STAT_HIDDEN;
217+
pt[p_id].load_1m->flags |= STAT_HIDDEN;
218+
pt[p_id].load_10m->flags |= STAT_HIDDEN;
219+
#ifdef PKG_MALLOC
220+
pt[p_id].pkg_total->flags |= STAT_HIDDEN;
221+
pt[p_id].pkg_used->flags |= STAT_HIDDEN;
222+
pt[p_id].pkg_rused->flags |= STAT_HIDDEN;
223+
pt[p_id].pkg_mused->flags |= STAT_HIDDEN;
224+
pt[p_id].pkg_free->flags |= STAT_HIDDEN;
225+
pt[p_id].pkg_frags->flags |= STAT_HIDDEN;
226+
#endif
210227
}
211228

212229

@@ -258,11 +275,6 @@ int internal_fork(char *proc_desc, unsigned int flags,
258275
pt[new_idx].ipc_pipe[1]=pt[new_idx].ipc_pipe_holder[1];
259276
}
260277

261-
if (register_process_stats(new_idx)<0) {
262-
LM_ERR("failed to create stats for future proc %d\n", process_no);
263-
return -1;
264-
}
265-
266278
pt[new_idx].pid = 0;
267279
pt[new_idx].flags = OSS_PROC_IS_RUNNING;
268280

@@ -281,6 +293,17 @@ int internal_fork(char *proc_desc, unsigned int flags,
281293
pt[process_no].pid = getpid();
282294
pt[process_no].flags |= flags;
283295
pt[process_no].type = type;
296+
/* activate its load & pkg statistics */
297+
pt[process_no].load_rt->flags &= (~STAT_HIDDEN);
298+
pt[process_no].load_1m->flags &= (~STAT_HIDDEN);
299+
pt[process_no].load_10m->flags &= (~STAT_HIDDEN);
300+
#ifdef PKG_MALLOC
301+
pt[process_no].pkg_used->flags &= (~STAT_HIDDEN);
302+
pt[process_no].pkg_rused->flags &= (~STAT_HIDDEN);
303+
pt[process_no].pkg_mused->flags &= (~STAT_HIDDEN);
304+
pt[process_no].pkg_free->flags &= (~STAT_HIDDEN);
305+
pt[process_no].pkg_frags->flags &= (~STAT_HIDDEN);
306+
#endif
284307
/* each children need a unique seed */
285308
seed_child(seed);
286309
init_log_level();
@@ -412,7 +435,7 @@ void check_and_adjust_number_of_workers(void)
412435
if (pt[i].type != pg->type || pg->si_filter!=pt[i].pg_filter)
413436
continue;
414437

415-
load += get_stat_val( pt[i].load.load_rt );
438+
load += get_stat_val( pt[i].load_rt );
416439
procs_no++;
417440

418441
}

pt.h

+13-1
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,20 @@ struct process_table {
7171
/* used when resetting the log level */
7272
int default_log_level;
7373

74+
/* statistics of this process - they do not change during runtime,
75+
* even when the proc is terminated or respawn - we just hide/unhide */
76+
stat_var *load_rt;
77+
stat_var *load_1m;
78+
stat_var *load_10m;
79+
stat_var *pkg_total;
80+
stat_var *pkg_used;
81+
stat_var *pkg_rused;
82+
stat_var *pkg_mused;
83+
stat_var *pkg_free;
84+
stat_var *pkg_frags;
85+
7486
/* the load statistic of this process */
75-
struct proc_load load;
87+
struct proc_load_info load;
7688
};
7789

7890
typedef int (*forked_proc_func)(int i);

pt_load.c

+45-35
Original file line numberDiff line numberDiff line change
@@ -363,50 +363,60 @@ unsigned int pt_get_10m_loadall(int _)
363363
}
364364

365365

366-
int register_process_load_stats(int pno)
366+
int register_processes_load_stats(int procs_no)
367367
{
368368
char *stat_name;
369369
str stat_prefix;
370370
char *pno_s;
371371
str name;
372+
int pno;
372373

373-
pno_s = int2str( (unsigned int)pno, NULL);
374+
/* build the stats and register them for each potential process
375+
* skipp the attendant, id 0 */
376+
for( pno=1 ; pno<procs_no ; pno++) {
374377

375-
stat_prefix.s = "load-proc";
376-
stat_prefix.len = sizeof("load-proc")-1;
377-
if ( (stat_name = build_stat_name( &stat_prefix, pno_s)) == 0 ||
378-
register_stat2( "load", stat_name, (stat_var**)pt_get_rt_proc_load,
379-
STAT_IS_FUNC, (void*)(long)pno, 0) != 0) {
380-
LM_ERR("failed to add RT load stat for process %d\n",pno);
381-
return -1;
382-
}
383-
name.s = stat_name;
384-
name.len = strlen(stat_name);
385-
pt[pno].load.load_rt = get_stat(&name);
386-
387-
stat_prefix.s = "load1m-proc";
388-
stat_prefix.len = sizeof("load1m-proc")-1;
389-
if ( (stat_name = build_stat_name( &stat_prefix, pno_s)) == 0 ||
390-
register_stat2( "load", stat_name, (stat_var**)pt_get_1m_proc_load,
391-
STAT_IS_FUNC, (void*)(long)pno, 0) != 0) {
392-
LM_ERR("failed to add RT load stat for process %d\n",pno);
393-
return -1;
394-
}
395-
name.s = stat_name;
396-
name.len = strlen(stat_name);
397-
pt[pno].load.load_1m = get_stat(&name);
398-
399-
stat_prefix.s = "load10m-proc";
400-
stat_prefix.len = sizeof("load10m-proc")-1;
401-
if ( (stat_name = build_stat_name( &stat_prefix, pno_s)) == 0 ||
402-
register_stat2( "load", stat_name, (stat_var**)pt_get_10m_proc_load,
403-
STAT_IS_FUNC, (void*)(long)pno, 0) != 0) {
404-
LM_ERR("failed to add RT load stat for process %d\n",pno);
378+
pno_s = int2str( (unsigned int)pno, NULL);
379+
380+
stat_prefix.s = "load-proc";
381+
stat_prefix.len = sizeof("load-proc")-1;
382+
if ( (stat_name = build_stat_name( &stat_prefix, pno_s)) == 0 ||
383+
register_stat2( "load", stat_name, (stat_var**)pt_get_rt_proc_load,
384+
STAT_IS_FUNC, (void*)(long)pno, 0) != 0) {
385+
LM_ERR("failed to add RT load stat for process %d\n",pno);
405386
return -1;
387+
}
388+
name.s = stat_name;
389+
name.len = strlen(stat_name);
390+
pt[pno].load_rt = get_stat(&name);
391+
pt[pno].load_rt->flags |= STAT_HIDDEN;
392+
393+
stat_prefix.s = "load1m-proc";
394+
stat_prefix.len = sizeof("load1m-proc")-1;
395+
if ( (stat_name = build_stat_name( &stat_prefix, pno_s)) == 0 ||
396+
register_stat2( "load", stat_name, (stat_var**)pt_get_1m_proc_load,
397+
STAT_IS_FUNC, (void*)(long)pno, 0) != 0) {
398+
LM_ERR("failed to add RT load stat for process %d\n",pno);
399+
return -1;
400+
}
401+
name.s = stat_name;
402+
name.len = strlen(stat_name);
403+
pt[pno].load_1m = get_stat(&name);
404+
pt[pno].load_1m->flags |= STAT_HIDDEN;
405+
406+
stat_prefix.s = "load10m-proc";
407+
stat_prefix.len = sizeof("load10m-proc")-1;
408+
if ( (stat_name = build_stat_name( &stat_prefix, pno_s)) == 0 ||
409+
register_stat2( "load", stat_name, (stat_var**)pt_get_10m_proc_load,
410+
STAT_IS_FUNC, (void*)(long)pno, 0) != 0) {
411+
LM_ERR("failed to add RT load stat for process %d\n",pno);
412+
return -1;
413+
}
414+
name.s = stat_name;
415+
name.len = strlen(stat_name);
416+
pt[pno].load_10m = get_stat(&name);
417+
pt[pno].load_10m->flags |= STAT_HIDDEN;
418+
406419
}
407-
name.s = stat_name;
408-
name.len = strlen(stat_name);
409-
pt[pno].load.load_10m = get_stat(&name);
410420

411421
return 0;
412422
}

pt_load.h

+2-7
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
#define LT_1m_RATIO (0.1)
4040

4141

42-
struct proc_load {
42+
struct proc_load_info {
4343
/* sampling array for the Short Time load calculation (real time
4444
* load or 1 second time-window load)*/
4545
unsigned short ST_window[ST_WINDOW_SIZE];
@@ -54,11 +54,6 @@ struct proc_load {
5454
/* set to 1 when the process switched to busy; set on 0 if idle */
5555
unsigned char is_busy;
5656

57-
/* the load statistics of the process */
58-
stat_var *load_rt;
59-
stat_var *load_1m;
60-
stat_var *load_10m;
61-
6257
};
6358

6459
void pt_become_active(void);
@@ -78,6 +73,6 @@ unsigned int pt_get_1m_proc_load(int pid);
7873
unsigned int pt_get_10m_proc_load(int pid);
7974

8075
/* OpenSIPS startup */
81-
int register_process_load_stats(int process_no);
76+
int register_processes_load_stats(int procs_no);
8277

8378
#endif

0 commit comments

Comments
 (0)