blob: f82a6ac20123233df1dd6b8292a555327dc57eb1 [file] [log] [blame] [raw]
Igor Sysoev7d66b1f2004-10-05 15:39:18 +00001
2/*
3 * Copyright (C) Igor Sysoev
4 */
5
6
7#include <ngx_config.h>
8#include <ngx_core.h>
9
10
11/* FreeBSD 3.0 at least */
Igor Sysoev34657fc2004-11-11 14:00:51 +000012char ngx_freebsd_kern_ostype[16];
13char ngx_freebsd_kern_osrelease[128];
Igor Sysoev7d66b1f2004-10-05 15:39:18 +000014int ngx_freebsd_kern_osreldate;
15int ngx_freebsd_hw_ncpu;
16int ngx_freebsd_net_inet_tcp_sendspace;
Igor Sysoevc70429e2005-03-19 12:35:58 +000017int ngx_freebsd_kern_ipc_somaxconn;
Igor Sysoev7d66b1f2004-10-05 15:39:18 +000018
19/* FreeBSD 4.9 */
20int ngx_freebsd_machdep_hlt_logical_cpus;
21
22/* FreeBSD 5.0 */
23int ngx_freebsd_kern_ipc_zero_copy_send;
24
25
26ngx_uint_t ngx_freebsd_sendfile_nbytes_bug;
27ngx_uint_t ngx_freebsd_use_tcp_nopush;
28
29
Igor Sysoevb3e4c1f2005-09-06 16:02:57 +000030static ngx_os_io_t ngx_freebsd_io = {
Igor Sysoev7d66b1f2004-10-05 15:39:18 +000031 ngx_unix_recv,
32 ngx_readv_chain,
33 ngx_unix_send,
Igor Sysoeva9c1bbe2004-11-25 14:10:55 +000034#if (NGX_HAVE_SENDFILE)
Igor Sysoev7d66b1f2004-10-05 15:39:18 +000035 ngx_freebsd_sendfile_chain,
36 NGX_IO_SENDFILE
37#else
38 ngx_writev_chain,
39 0
40#endif
41};
42
43
44typedef struct {
45 char *name;
46 int *value;
47 size_t size;
48 ngx_uint_t exists;
49} sysctl_t;
50
51
52sysctl_t sysctls[] = {
53 { "hw.ncpu",
54 &ngx_freebsd_hw_ncpu,
55 sizeof(int), 0 },
56
57 { "machdep.hlt_logical_cpus",
58 &ngx_freebsd_machdep_hlt_logical_cpus,
59 sizeof(int), 0 },
60
61 { "net.inet.tcp.sendspace",
62 &ngx_freebsd_net_inet_tcp_sendspace,
63 sizeof(int), 0 },
64
Igor Sysoevc70429e2005-03-19 12:35:58 +000065 { "kern.ipc.somaxconn",
66 &ngx_freebsd_kern_ipc_somaxconn,
67 sizeof(int), 0 },
68
Igor Sysoev7d66b1f2004-10-05 15:39:18 +000069 { "kern.ipc.zero_copy.send",
70 &ngx_freebsd_kern_ipc_zero_copy_send,
71 sizeof(int), 0 },
72
73 { NULL, NULL, 0, 0 }
74};
75
76
Igor Sysoevb3e4c1f2005-09-06 16:02:57 +000077void
78ngx_debug_init()
Igor Sysoev7d66b1f2004-10-05 15:39:18 +000079{
Igor Sysoev868c3422005-09-30 14:31:19 +000080#if (NGX_DEBUG_MALLOC)
Igor Sysoev7d66b1f2004-10-05 15:39:18 +000081
82#if __FreeBSD_version >= 500014
83 _malloc_options = "J";
84#else
85 malloc_options = "J";
86#endif
87
88#endif
89}
90
91
Igor Sysoevb3e4c1f2005-09-06 16:02:57 +000092ngx_int_t
93ngx_os_specific_init(ngx_log_t *log)
Igor Sysoev7d66b1f2004-10-05 15:39:18 +000094{
Igor Sysoevc70429e2005-03-19 12:35:58 +000095 int version, somaxconn;
Igor Sysoev7d66b1f2004-10-05 15:39:18 +000096 size_t size;
97 ngx_err_t err;
98 ngx_uint_t i;
99
100 size = sizeof(ngx_freebsd_kern_ostype);
101 if (sysctlbyname("kern.ostype",
102 ngx_freebsd_kern_ostype, &size, NULL, 0) == -1) {
103 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
104 "sysctlbyname(kern.ostype) failed");
Igor Sysoev34657fc2004-11-11 14:00:51 +0000105
106 if (ngx_errno != NGX_ENOMEM) {
107 return NGX_ERROR;
108 }
109
110 ngx_freebsd_kern_ostype[size - 1] = '\0';
Igor Sysoev7d66b1f2004-10-05 15:39:18 +0000111 }
112
113 size = sizeof(ngx_freebsd_kern_osrelease);
114 if (sysctlbyname("kern.osrelease",
115 ngx_freebsd_kern_osrelease, &size, NULL, 0) == -1) {
116 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
117 "sysctlbyname(kern.osrelease) failed");
Igor Sysoev34657fc2004-11-11 14:00:51 +0000118
119 if (ngx_errno != NGX_ENOMEM) {
120 return NGX_ERROR;
121 }
122
123 ngx_freebsd_kern_osrelease[size - 1] = '\0';
Igor Sysoev7d66b1f2004-10-05 15:39:18 +0000124 }
125
126
127 size = sizeof(int);
128 if (sysctlbyname("kern.osreldate",
129 &ngx_freebsd_kern_osreldate, &size, NULL, 0) == -1) {
130 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
131 "sysctlbyname(kern.osreldate) failed");
132 return NGX_ERROR;
133 }
134
135 version = ngx_freebsd_kern_osreldate;
136
137
Igor Sysoeva9c1bbe2004-11-25 14:10:55 +0000138#if (NGX_HAVE_SENDFILE)
Igor Sysoev7d66b1f2004-10-05 15:39:18 +0000139
140 /*
141 * The determination of the sendfile() "nbytes bug" is complex enough.
142 * There are two sendfile() syscalls: a new #393 has no bug while
143 * an old #336 has the bug in some versions and has not in others.
144 * Besides libc_r wrapper also emulates the bug in some versions.
145 * There is no way to say exactly if syscall #336 in FreeBSD circa 4.6
146 * has the bug. We use the algorithm that is correct at least for
147 * RELEASEs and for syscalls only (not libc_r wrapper).
148 *
149 * 4.6.1-RELEASE and below have the bug
150 * 4.6.2-RELEASE and above have the new syscall
151 *
152 * We detect the new sendfile() syscall available at the compile time
153 * to allow an old binary to run correctly on an updated FreeBSD system.
154 */
155
156#if (__FreeBSD__ == 4 && __FreeBSD_version >= 460102) \
157 || __FreeBSD_version == 460002 || __FreeBSD_version >= 500039
158
159 /* a new syscall without the bug */
160
161 ngx_freebsd_sendfile_nbytes_bug = 0;
162
163#else
164
165 /* an old syscall that may have the bug */
166
167 ngx_freebsd_sendfile_nbytes_bug = 1;
168
169#endif
170
Igor Sysoeva9c1bbe2004-11-25 14:10:55 +0000171#endif /* NGX_HAVE_SENDFILE */
Igor Sysoev7d66b1f2004-10-05 15:39:18 +0000172
173
174 if ((version < 500000 && version >= 440003) || version >= 500017) {
175 ngx_freebsd_use_tcp_nopush = 1;
176 }
177
178
179 for (i = 0; sysctls[i].name; i++) {
180 *sysctls[i].value = 0;
181 size = sysctls[i].size;
182
183 if (sysctlbyname(sysctls[i].name, sysctls[i].value, &size, NULL, 0)
184 == 0)
185 {
186 sysctls[i].exists = 1;
187 continue;
188 }
189
190 err = ngx_errno;
191
192 if (err == NGX_ENOENT) {
193 continue;
194 }
195
196#if 0
197 if (sysctls[i].value == &ngx_freebsd_machdep_hlt_logical_cpus) {
198 continue;
199 }
200#endif
201
202 ngx_log_error(NGX_LOG_ALERT, log, err,
203 "sysctlbyname(%s) failed", sysctls[i].name);
204 return NGX_ERROR;
205 }
206
207 if (ngx_freebsd_machdep_hlt_logical_cpus) {
208 ngx_ncpu = ngx_freebsd_hw_ncpu / 2;
209 } else {
210 ngx_ncpu = ngx_freebsd_hw_ncpu;
211 }
212
Igor Sysoevc70429e2005-03-19 12:35:58 +0000213 if (version < 600008) {
214 somaxconn = 32767;
215 } else {
216 somaxconn = 65535;
217 }
218
219 if (ngx_freebsd_kern_ipc_somaxconn > somaxconn) {
220 ngx_log_error(NGX_LOG_ALERT, log, 0,
221 "sysctl kern.ipc.somaxconn must be no more than %d",
222 somaxconn);
223 return NGX_ERROR;
224 }
Igor Sysoev916794d2004-10-11 15:06:17 +0000225
Igor Sysoev36bd1912004-12-02 18:46:29 +0000226 ngx_tcp_nodelay_and_tcp_nopush = 1;
227
Igor Sysoevb3e4c1f2005-09-06 16:02:57 +0000228 ngx_os_io = ngx_freebsd_io;
Igor Sysoev36bd1912004-12-02 18:46:29 +0000229
Igor Sysoevb3e4c1f2005-09-06 16:02:57 +0000230 return NGX_OK;
Igor Sysoev7d66b1f2004-10-05 15:39:18 +0000231}
232
233
Igor Sysoevb3e4c1f2005-09-06 16:02:57 +0000234void
235ngx_os_specific_status(ngx_log_t *log)
Igor Sysoev7d66b1f2004-10-05 15:39:18 +0000236{
237 ngx_uint_t i;
238
Igor Sysoevbab33f22005-07-22 13:22:07 +0000239 ngx_log_error(NGX_LOG_NOTICE, log, 0, "OS: %s %s",
Igor Sysoev7d66b1f2004-10-05 15:39:18 +0000240 ngx_freebsd_kern_ostype, ngx_freebsd_kern_osrelease);
241
242#ifdef __DragonFly_version
Igor Sysoevbab33f22005-07-22 13:22:07 +0000243 ngx_log_error(NGX_LOG_NOTICE, log, 0,
Igor Sysoev7d66b1f2004-10-05 15:39:18 +0000244 "kern.osreldate: %d, built on %d",
245 ngx_freebsd_kern_osreldate, __DragonFly_version);
246#else
Igor Sysoevbab33f22005-07-22 13:22:07 +0000247 ngx_log_error(NGX_LOG_NOTICE, log, 0,
Igor Sysoev7d66b1f2004-10-05 15:39:18 +0000248 "kern.osreldate: %d, built on %d",
249 ngx_freebsd_kern_osreldate, __FreeBSD_version);
250#endif
251
252 for (i = 0; sysctls[i].name; i++) {
253 if (sysctls[i].exists) {
Igor Sysoevbab33f22005-07-22 13:22:07 +0000254 ngx_log_error(NGX_LOG_NOTICE, log, 0, "%s: %d",
Igor Sysoev7d66b1f2004-10-05 15:39:18 +0000255 sysctls[i].name, *sysctls[i].value);
256 }
257 }
Igor Sysoev7d66b1f2004-10-05 15:39:18 +0000258}