Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ngx_freebsd_init.c
Go to the documentation of this file.
1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) Nginx, Inc.
5  */
6 
7 
8 #include <ngx_config.h>
9 #include <ngx_core.h>
10 
11 
12 /* FreeBSD 3.0 at least */
19 
20 /* FreeBSD 4.9 */
22 
23 
26 
28 
29 
30 static ngx_os_io_t ngx_freebsd_io = {
35 #if (NGX_HAVE_SENDFILE)
38 #else
40  0
41 #endif
42 };
43 
44 
45 typedef struct {
46  char *name;
47  void *value;
48  size_t size;
49  ngx_uint_t exists;
50 } sysctl_t;
51 
52 
54  { "hw.ncpu",
56  sizeof(ngx_freebsd_hw_ncpu), 0 },
57 
58  { "machdep.hlt_logical_cpus",
61 
62  { "net.inet.tcp.sendspace",
65 
66  { "kern.ipc.somaxconn",
68  sizeof(ngx_freebsd_kern_ipc_somaxconn), 0 },
69 
70  { NULL, NULL, 0, 0 }
71 };
72 
73 
74 void
76 {
77 #if (NGX_DEBUG_MALLOC)
78 
79 #if __FreeBSD_version >= 500014 && __FreeBSD_version < 1000011
80  _malloc_options = "J";
81 #elif __FreeBSD_version < 500014
82  malloc_options = "J";
83 #endif
84 
85  ngx_debug_malloc = 1;
86 
87 #else
88  char *mo;
89 
90  mo = getenv("MALLOC_OPTIONS");
91 
92  if (mo && ngx_strchr(mo, 'J')) {
93  ngx_debug_malloc = 1;
94  }
95 #endif
96 }
97 
98 
101 {
102  int version;
103  size_t size;
104  ngx_err_t err;
105  ngx_uint_t i;
106 
107  size = sizeof(ngx_freebsd_kern_ostype);
108  if (sysctlbyname("kern.ostype",
109  ngx_freebsd_kern_ostype, &size, NULL, 0) == -1) {
111  "sysctlbyname(kern.ostype) failed");
112 
113  if (ngx_errno != NGX_ENOMEM) {
114  return NGX_ERROR;
115  }
116 
117  ngx_freebsd_kern_ostype[size - 1] = '\0';
118  }
119 
120  size = sizeof(ngx_freebsd_kern_osrelease);
121  if (sysctlbyname("kern.osrelease",
122  ngx_freebsd_kern_osrelease, &size, NULL, 0) == -1) {
124  "sysctlbyname(kern.osrelease) failed");
125 
126  if (ngx_errno != NGX_ENOMEM) {
127  return NGX_ERROR;
128  }
129 
130  ngx_freebsd_kern_osrelease[size - 1] = '\0';
131  }
132 
133 
134  size = sizeof(int);
135  if (sysctlbyname("kern.osreldate",
136  &ngx_freebsd_kern_osreldate, &size, NULL, 0) == -1) {
138  "sysctlbyname(kern.osreldate) failed");
139  return NGX_ERROR;
140  }
141 
142  version = ngx_freebsd_kern_osreldate;
143 
144 
145 #if (NGX_HAVE_SENDFILE)
146 
147  /*
148  * The determination of the sendfile() "nbytes bug" is complex enough.
149  * There are two sendfile() syscalls: a new #393 has no bug while
150  * an old #336 has the bug in some versions and has not in others.
151  * Besides libc_r wrapper also emulates the bug in some versions.
152  * There is no way to say exactly if syscall #336 in FreeBSD circa 4.6
153  * has the bug. We use the algorithm that is correct at least for
154  * RELEASEs and for syscalls only (not libc_r wrapper).
155  *
156  * 4.6.1-RELEASE and below have the bug
157  * 4.6.2-RELEASE and above have the new syscall
158  *
159  * We detect the new sendfile() syscall available at the compile time
160  * to allow an old binary to run correctly on an updated FreeBSD system.
161  */
162 
163 #if (__FreeBSD__ == 4 && __FreeBSD_version >= 460102) \
164  || __FreeBSD_version == 460002 || __FreeBSD_version >= 500039
165 
166  /* a new syscall without the bug */
167 
169 
170 #else
171 
172  /* an old syscall that may have the bug */
173 
175 
176 #endif
177 
178 #endif /* NGX_HAVE_SENDFILE */
179 
180 
181  if ((version < 500000 && version >= 440003) || version >= 500017) {
183  }
184 
185 
186  for (i = 0; sysctls[i].name; i++) {
187  size = sysctls[i].size;
188 
189  if (sysctlbyname(sysctls[i].name, sysctls[i].value, &size, NULL, 0)
190  == 0)
191  {
192  sysctls[i].exists = 1;
193  continue;
194  }
195 
196  err = ngx_errno;
197 
198  if (err == NGX_ENOENT) {
199  continue;
200  }
201 
202  ngx_log_error(NGX_LOG_ALERT, log, err,
203  "sysctlbyname(%s) failed", sysctls[i].name);
204  return NGX_ERROR;
205  }
206 
209 
210  } else {
212  }
213 
214  if (version < 600008 && ngx_freebsd_kern_ipc_somaxconn > 32767) {
216  "sysctl kern.ipc.somaxconn must be less than 32768");
217  return NGX_ERROR;
218  }
219 
221 
222  ngx_os_io = ngx_freebsd_io;
223 
224  return NGX_OK;
225 }
226 
227 
228 void
230 {
231  u_long value;
232  ngx_uint_t i;
233 
234  ngx_log_error(NGX_LOG_NOTICE, log, 0, "OS: %s %s",
236 
237 #ifdef __DragonFly_version
239  "kern.osreldate: %d, built on %d",
240  ngx_freebsd_kern_osreldate, __DragonFly_version);
241 #else
243  "kern.osreldate: %d, built on %d",
244  ngx_freebsd_kern_osreldate, __FreeBSD_version);
245 #endif
246 
247  for (i = 0; sysctls[i].name; i++) {
248  if (sysctls[i].exists) {
249  if (sysctls[i].size == sizeof(long)) {
250  value = *(long *) sysctls[i].value;
251 
252  } else {
253  value = *(int *) sysctls[i].value;
254  }
255 
256  ngx_log_error(NGX_LOG_NOTICE, log, 0, "%s: %l",
257  sysctls[i].name, value);
258  }
259  }
260 }