Skip to content

Commit 12d27ab

Browse files
committed
Fixed autodetection of the reactor size (open files)
If we auto-detect the size of the reactor(via rulimit), be sure we have enough pkg memory (and do the necessary correction). If the open files limit is given, warn if the reactor will use too much memory. Thanks to MAxim Sobolev for reporting it via mailing list and to @cepehutu Closes OpenSIPS#778 (cherry picked from commit 6dd88ab)
1 parent 5b7b5f7 commit 12d27ab

File tree

7 files changed

+89
-17
lines changed

7 files changed

+89
-17
lines changed

daemonize.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,9 @@ int do_suid(const int uid, const int gid)
449449

450450

451451
/*!
452-
* \brief try to increase the open file limit
453-
* \param target target that should be reached
452+
* \brief try to increase the open file limit to the value given by the global
453+
* option "open_files_limit" ; the value is updated back in case of a
454+
* partial increase of the limit
454455
* \return return 0 on success, -1 on error
455456
*/
456457
int set_open_fds_limit(void)
@@ -465,11 +466,6 @@ int set_open_fds_limit(void)
465466
orig=lim;
466467
LM_DBG("current open file limits: %lu/%lu\n",
467468
(unsigned long)lim.rlim_cur, (unsigned long)lim.rlim_max);
468-
if (open_files_limit<=0) {
469-
/* if not set from cfg, we just read the existing value */
470-
open_files_limit = lim.rlim_cur;
471-
goto done;
472-
}
473469
if ((lim.rlim_cur==RLIM_INFINITY) || (open_files_limit<=lim.rlim_cur))
474470
/* nothing to do (we do no reduce the limit) */
475471
goto done;

main.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
* the TCP, UDP, timer and fifo children.
6868
*/
6969

70-
70+
#include "reactor_defs.h" /*keep this first*/
7171
#include <stdio.h>
7272
#include <stdlib.h>
7373
#include <errno.h>
@@ -81,7 +81,6 @@
8181
#include <netinet/ip.h>
8282
#include <arpa/inet.h>
8383
#include <sys/utsname.h>
84-
#include <sys/types.h>
8584
#include <sys/stat.h>
8685
#include <sys/mman.h>
8786
#include <fcntl.h>
@@ -1154,9 +1153,11 @@ int main(int argc, char** argv)
11541153

11551154
if (disable_core_dump) set_core_dump(0, 0);
11561155
else set_core_dump(1, shm_mem_size+pkg_mem_size+4*1024*1024);
1157-
if(set_open_fds_limit()<0){
1158-
LM_ERR("ERROR: error could not increase file limits\n");
1159-
goto error;
1156+
if (open_files_limit>0) {
1157+
if(set_open_fds_limit()<0){
1158+
LM_ERR("ERROR: error could not increase file limits\n");
1159+
goto error;
1160+
}
11601161
}
11611162

11621163
/* print OpenSIPS version to log for history tracking */
@@ -1167,6 +1168,12 @@ int main(int argc, char** argv)
11671168
LM_INFO("using %ld Mb private memory per process\n",
11681169
((pkg_mem_size/1024)/1024));
11691170

1171+
/* init async reactor */
1172+
if (init_reactor_size()<0) {
1173+
LM_CRIT("failed to init internal reactor, exiting...\n");
1174+
goto error;
1175+
}
1176+
11701177
/* init timer */
11711178
if (init_timer()<0){
11721179
LM_CRIT("could not initialize timer, exiting...\n");

net/net_tcp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1453,7 +1453,7 @@ static void tcp_main_server(void)
14531453

14541454
/* we run in a separate, dedicated process, with its own reactor
14551455
* (reactors are per process) */
1456-
if (init_worker_reactor("TCP_main", open_files_limit, RCT_PRIO_MAX)<0)
1456+
if (init_worker_reactor("TCP_main", RCT_PRIO_MAX)<0)
14571457
goto error;
14581458

14591459
/* now start watching all the fds*/

net/net_tcp_proc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ void tcp_worker_proc( int unix_sock)
288288
{
289289
/* init reactor for TCP worker */
290290
tcpmain_sock=unix_sock; /* init com. socket */
291-
if ( init_worker_reactor("TCP_worker",open_files_limit,RCT_PRIO_MAX)<0 ) {
291+
if ( init_worker_reactor( "TCP_worker", RCT_PRIO_MAX)<0 ) {
292292
goto error;
293293
}
294294

net/net_udp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ inline static int handle_io(struct fd_map* fm, int idx,int event_type)
287287
int udp_rcv_loop( struct socket_info *si )
288288
{
289289
/* create the reactor for UDP proc */
290-
if ( init_worker_reactor("UDP_worker",open_files_limit,RCT_PRIO_MAX)<0 ) {
290+
if ( init_worker_reactor( "UDP_worker", RCT_PRIO_MAX)<0 ) {
291291
LM_ERR("failed to init reactor\n");
292292
goto error;
293293
}

reactor.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,74 @@
2323
* 2014-08-23 created (bogdan)
2424
*/
2525

26+
#include <sys/time.h>
27+
#include <sys/resource.h>
28+
2629
#include "io_wait.h"
30+
#include "globals.h"
2731

2832
/* one reactor per process variable */
2933
io_wait_h _worker_io;
34+
/* max number of fds per reactor */
35+
unsigned int reactor_size = 0;
36+
37+
#define FD_MEM_PERCENT 10
38+
39+
int init_reactor_size(void)
40+
{
41+
struct rlimit lim;
42+
int n, pc;
43+
44+
n = sizeof(struct fd_map) + sizeof(struct pollfd);
45+
46+
if (open_files_limit>0) {
47+
48+
/* the fd limit was explicitly set, so just follow but only warn
49+
* if too much memory is to consumed by reactor */
50+
pc = 100*n*open_files_limit / pkg_mem_size;
51+
if (pc>=80) {
52+
LM_ERR("required memory for a %d files reactor is over 80%% of"
53+
" the configured pkg mem (%luMb)\n",
54+
open_files_limit, pkg_mem_size);
55+
LM_ERR("Please consider increasing the pkg memory or reduce the"
56+
" limit of open files...Exiting\n");
57+
return -1;
58+
} else if (pc>=50) {
59+
LM_WARN("required memory for a %d files reactor is over 50%% of"
60+
" the configured pkg mem (%luMb)\n",
61+
open_files_limit, pkg_mem_size);
62+
LM_WARN("PKG memory may not be enough at runtime (consider "
63+
"increasing it), still continuing\n");
64+
}
65+
/* seems to have enough mem -> size the reactor based on open files */
66+
reactor_size = open_files_limit;
67+
68+
} else {
69+
70+
/* auto detect the limit of open files */
71+
if (getrlimit(RLIMIT_NOFILE, &lim)<0){
72+
LM_ERR("cannot get the maximum number of file descriptors: %s\n",
73+
strerror(errno));
74+
return -1;
75+
}
76+
77+
/* calculate the size to fit into 10% PKG mem */
78+
reactor_size = pkg_mem_size * FD_MEM_PERCENT / (100*n);
79+
80+
if (reactor_size<lim.rlim_cur) {
81+
LM_WARN("shrinking reactor size from %lu (autodetected via rlimit)"
82+
" to %d (limited by memory of %d%% from %luMb)\n",
83+
lim.rlim_cur,reactor_size,FD_MEM_PERCENT,pkg_mem_size);
84+
LM_WARN("use 'open_files_limit' to enforce other limit or "
85+
"increase PKG memory\n");
86+
} else {
87+
/* enouhg memory, use as limit the fd limit */
88+
reactor_size = lim.rlim_cur;
89+
}
90+
}
91+
92+
LM_DBG("using reactor size %d\n",reactor_size);
93+
94+
return 0;
95+
}
3096

reactor_defs.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,12 @@ enum fd_types { F_NONE=0,
6868
};
6969

7070
extern io_wait_h _worker_io;
71+
extern unsigned int reactor_size;
7172

72-
#define init_worker_reactor( _name, _max_fd, _prio_max) \
73-
init_io_wait(&_worker_io, _name, _max_fd, io_poll_method, _prio_max)
73+
int init_reactor_size(void);
74+
75+
#define init_worker_reactor( _name, _prio_max) \
76+
init_io_wait(&_worker_io, _name, reactor_size, io_poll_method, _prio_max)
7477

7578
#define reactor_add_reader( _fd, _type, _prio, _data) \
7679
io_watch_add(&_worker_io, _fd, _type, _data, _prio, IO_WATCH_READ)

0 commit comments

Comments
 (0)