Line data Source code
1 : #include "configure.h"
2 :
3 0 : #define NAME "sysctl"
4 :
5 : #include "../../../platform/fd_file_util.h"
6 : #include "../../../../discof/restore/utils/fd_sshttp.h"
7 :
8 : #include <errno.h>
9 : #include <stdio.h>
10 : #include <linux/capability.h>
11 :
12 : static void
13 : init_perm( fd_cap_chk_t * chk,
14 0 : config_t const * config FD_PARAM_UNUSED ) {
15 0 : fd_cap_chk_cap( chk, NAME, CAP_SYS_ADMIN, "set kernel parameters in `/proc/sys`" );
16 0 : }
17 :
18 0 : #define ENFORCE_MINIMUM 0
19 0 : #define WARN_MINIMUM 1
20 0 : #define WARN_EXACT 2
21 :
22 : typedef struct {
23 : char const * path;
24 : ulong value;
25 : int mode;
26 : int allow_missing;
27 : } sysctl_param_t;
28 :
29 : static const sysctl_param_t params[] = {
30 : {
31 : "/proc/sys/vm/max_map_count", /* int */
32 : 1000000,
33 : ENFORCE_MINIMUM,
34 : 0,
35 : },
36 : {
37 : "/proc/sys/fs/file-max", /* ulong */
38 : CONFIGURE_NR_OPEN_FILES,
39 : ENFORCE_MINIMUM,
40 : 0,
41 : },
42 : {
43 : "/proc/sys/fs/nr_open", /* uint */
44 : CONFIGURE_NR_OPEN_FILES,
45 : ENFORCE_MINIMUM,
46 : 0,
47 : },
48 : {
49 : "/proc/sys/net/core/rmem_max", /* int */
50 : FD_SSHTTP_SO_RCVBUF,
51 : ENFORCE_MINIMUM,
52 : 0,
53 : },
54 : {
55 : "/proc/sys/kernel/numa_balancing", /* int? */
56 : 0,
57 : WARN_EXACT,
58 : 1,
59 : },
60 : {0}
61 : };
62 :
63 : static sysctl_param_t xdp_params[] = {
64 : {
65 : "/proc/sys/net/ipv4/conf/lo/rp_filter",
66 : 2,
67 : ENFORCE_MINIMUM,
68 : 0,
69 : },
70 : {
71 : "/proc/sys/net/ipv4/conf/lo/accept_local",
72 : 1,
73 : ENFORCE_MINIMUM,
74 : 0,
75 : },
76 : {
77 : "/proc/sys/net/core/bpf_jit_enable",
78 : 1,
79 : WARN_MINIMUM,
80 : 0,
81 : },
82 : {
83 : "/proc/sys/net/ipv4/conf/lo/route_localnet",
84 : 1,
85 : ENFORCE_MINIMUM,
86 : 1,
87 : },
88 : {
89 : "/proc/sys/net/core/wmem_max",
90 : 0,
91 : ENFORCE_MINIMUM,
92 : 0,
93 : },
94 : {0}
95 : };
96 :
97 : static sysctl_param_t sock_params[] = {
98 : {
99 : "/proc/sys/net/core/rmem_max",
100 : 0,
101 : ENFORCE_MINIMUM,
102 : 0,
103 : },
104 : {
105 : "/proc/sys/net/core/wmem_max",
106 : 0,
107 : ENFORCE_MINIMUM,
108 : 0,
109 : },
110 : {0}
111 : };
112 :
113 : static sysctl_param_t gui_params[] = {
114 : {
115 : "/proc/sys/net/core/wmem_max",
116 : 4194304,
117 : ENFORCE_MINIMUM,
118 : 0,
119 : },
120 : {0}
121 : };
122 :
123 : static void
124 0 : init_param_list( sysctl_param_t const * list ) {
125 0 : for( sysctl_param_t const * p=list; p->path; p++ ) {
126 0 : ulong param;
127 0 : if( FD_UNLIKELY( -1==fd_file_util_read_ulong( p->path, ¶m ) ) ) {
128 : /* If the syctl file does not exist in /proc/sys, it's likely it
129 : doesn't exist anywhere else */
130 0 : if( FD_UNLIKELY( p->allow_missing && errno==ENOENT ) ) continue;
131 :
132 0 : FD_LOG_ERR(( "could not read kernel parameter `%s`, system might not support configuring sysctl (%i-%s)", p->path, errno, fd_io_strerror( errno ) ));
133 0 : }
134 0 : switch( p->mode ) {
135 0 : case ENFORCE_MINIMUM:
136 0 : if( FD_UNLIKELY( param<(p->value) ) ) {
137 0 : FD_LOG_NOTICE(( "%sRUN: `echo \"%lu\" > %s`%s", fd_log_style_dim(), p->value, p->path, fd_log_style_normal() ));
138 0 : if( FD_UNLIKELY( -1==fd_file_util_write_ulong( p->path, p->value ) ) )
139 0 : FD_LOG_ERR(( "could not set kernel parameter `%s` to %lu (%i-%s)", p->path, p->value, errno, fd_io_strerror( errno ) ));
140 0 : }
141 0 : break;
142 0 : default:
143 0 : break;
144 0 : }
145 0 : }
146 0 : }
147 :
148 : static void
149 0 : init( config_t const * config ) {
150 0 : init_param_list( params );
151 0 : if( 0==strcmp( config->net.provider, "xdp" ) ) {
152 0 : xdp_params[ 4 ].value = fd_ulong_min( (ulong)config->net.xdp.xdp_tx_queue_size*2048UL, (ulong)INT_MAX ); /* the XSK send buffer fd_xsk_init asks for */
153 0 : init_param_list( xdp_params );
154 0 : } else if( 0==strcmp( config->net.provider, "socket" ) ) {
155 0 : sock_params[ 0 ].value = config->net.socket.receive_buffer_size;
156 0 : sock_params[ 1 ].value = config->net.socket.send_buffer_size;
157 0 : init_param_list( sock_params );
158 0 : }
159 0 : if( config->tiles.gui.enabled ) init_param_list( gui_params );
160 0 : }
161 :
162 : static configure_result_t
163 0 : check_param_list( sysctl_param_t const * list ) {
164 0 : static int has_warned = 0;
165 :
166 0 : for( sysctl_param_t const * p=list; p->path; p++ ) {
167 0 : ulong param;
168 0 : if( FD_UNLIKELY( -1==fd_file_util_read_ulong( p->path, ¶m ) ) ) {
169 0 : if( FD_UNLIKELY( p->allow_missing && errno==ENOENT ) ) continue;
170 0 : FD_LOG_ERR(( "could not read kernel parameter `%s`, system might not support configuring sysctl (%i-%s)", p->path, errno, fd_io_strerror( errno ) ));
171 0 : }
172 0 : switch( p->mode ) {
173 0 : case ENFORCE_MINIMUM:
174 0 : if( FD_UNLIKELY( param<(p->value) ) )
175 0 : NOT_CONFIGURED( "kernel parameter `%s` is too low (got %lu but expected at least %lu)", p->path, param, p->value );
176 0 : break;
177 0 : case WARN_MINIMUM:
178 0 : if( FD_UNLIKELY( !has_warned && param<(p->value) ) )
179 0 : FD_LOG_WARNING(( "kernel parameter `%s` is too low (got %lu but expected at least %lu). Proceeding but performance may be reduced.", p->path, param, p->value ));
180 0 : break;
181 0 : case WARN_EXACT:
182 0 : if( FD_UNLIKELY( !has_warned && param!=(p->value) ) )
183 0 : FD_LOG_WARNING(( "kernel parameter `%s` is set to %lu, not the expected value of %lu. Proceeding but performance may be reduced.", p->path, param, p->value ));
184 0 : break;
185 0 : }
186 0 : }
187 :
188 0 : has_warned = 1;
189 :
190 0 : CONFIGURE_OK();
191 0 : }
192 :
193 : static configure_result_t
194 : check( config_t const * config,
195 0 : int check_type FD_PARAM_UNUSED ) {
196 0 : configure_result_t r;
197 :
198 0 : r = check_param_list( params );
199 0 : if( r.result!=CONFIGURE_OK ) return r;
200 :
201 0 : if( 0==strcmp( config->net.provider, "xdp" ) ) {
202 0 : xdp_params[ 4 ].value = fd_ulong_min( (ulong)config->net.xdp.xdp_tx_queue_size*2048UL, (ulong)INT_MAX ); /* the XSK send buffer fd_xsk_init asks for */
203 0 : r = check_param_list( xdp_params );
204 0 : } else if( 0==strcmp( config->net.provider, "socket" ) ) {
205 0 : sock_params[ 0 ].value = config->net.socket.receive_buffer_size;
206 0 : sock_params[ 1 ].value = config->net.socket.send_buffer_size;
207 0 : r = check_param_list( sock_params );
208 0 : } else if( 0==strcmp( config->net.provider, "mlx5" ) || 0==strcmp( config->net.provider, "iavf" ) ) {
209 : /* mlx5 and iavf have no provider-specific sysctls */
210 0 : } else {
211 0 : FD_LOG_ERR(( "unknown net provider: %s", config->net.provider ));
212 0 : }
213 0 : if( r.result!=CONFIGURE_OK ) return r;
214 :
215 0 : if( config->tiles.gui.enabled ) {
216 0 : r = check_param_list( gui_params );
217 0 : if( r.result!=CONFIGURE_OK ) return r;
218 0 : }
219 :
220 0 : CONFIGURE_OK();
221 0 : }
222 :
223 : configure_stage_t fd_cfg_stage_sysctl = {
224 : .name = NAME,
225 : .always_recreate = 0,
226 : .enabled = NULL,
227 : .init_perm = init_perm,
228 : .fini_perm = NULL,
229 : .init = init,
230 : .fini = NULL,
231 : .check = check,
232 : };
233 :
234 : #undef NAME
|