Annotation of embedaddon/nginx/src/os/unix/ngx_freebsd_init.c, revision 1.1.1.1

1.1       misho       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 */
                     13: char    ngx_freebsd_kern_ostype[16];
                     14: char    ngx_freebsd_kern_osrelease[128];
                     15: int     ngx_freebsd_kern_osreldate;
                     16: int     ngx_freebsd_hw_ncpu;
                     17: int     ngx_freebsd_kern_ipc_somaxconn;
                     18: u_long  ngx_freebsd_net_inet_tcp_sendspace;
                     19: 
                     20: /* FreeBSD 4.9 */
                     21: int     ngx_freebsd_machdep_hlt_logical_cpus;
                     22: 
                     23: 
                     24: ngx_uint_t  ngx_freebsd_sendfile_nbytes_bug;
                     25: ngx_uint_t  ngx_freebsd_use_tcp_nopush;
                     26: 
                     27: ngx_uint_t  ngx_debug_malloc;
                     28: 
                     29: 
                     30: static ngx_os_io_t ngx_freebsd_io = {
                     31:     ngx_unix_recv,
                     32:     ngx_readv_chain,
                     33:     ngx_udp_unix_recv,
                     34:     ngx_unix_send,
                     35: #if (NGX_HAVE_SENDFILE)
                     36:     ngx_freebsd_sendfile_chain,
                     37:     NGX_IO_SENDFILE
                     38: #else
                     39:     ngx_writev_chain,
                     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: 
                     53: sysctl_t sysctls[] = {
                     54:     { "hw.ncpu",
                     55:       &ngx_freebsd_hw_ncpu,
                     56:       sizeof(ngx_freebsd_hw_ncpu), 0 },
                     57: 
                     58:     { "machdep.hlt_logical_cpus",
                     59:       &ngx_freebsd_machdep_hlt_logical_cpus,
                     60:       sizeof(ngx_freebsd_machdep_hlt_logical_cpus), 0 },
                     61: 
                     62:     { "net.inet.tcp.sendspace",
                     63:       &ngx_freebsd_net_inet_tcp_sendspace,
                     64:       sizeof(ngx_freebsd_net_inet_tcp_sendspace), 0 },
                     65: 
                     66:     { "kern.ipc.somaxconn",
                     67:       &ngx_freebsd_kern_ipc_somaxconn,
                     68:       sizeof(ngx_freebsd_kern_ipc_somaxconn), 0 },
                     69: 
                     70:     { NULL, NULL, 0, 0 }
                     71: };
                     72: 
                     73: 
                     74: void
                     75: ngx_debug_init()
                     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: 
                     99: ngx_int_t
                    100: ngx_os_specific_init(ngx_log_t *log)
                    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) {
                    110:         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
                    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) {
                    123:         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
                    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) {
                    137:         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
                    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: 
                    168:     ngx_freebsd_sendfile_nbytes_bug = 0;
                    169: 
                    170: #else
                    171: 
                    172:     /* an old syscall that may have the bug */
                    173: 
                    174:     ngx_freebsd_sendfile_nbytes_bug = 1;
                    175: 
                    176: #endif
                    177: 
                    178: #endif /* NGX_HAVE_SENDFILE */
                    179: 
                    180: 
                    181:     if ((version < 500000 && version >= 440003) || version >= 500017) {
                    182:         ngx_freebsd_use_tcp_nopush = 1;
                    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: 
                    207:     if (ngx_freebsd_machdep_hlt_logical_cpus) {
                    208:         ngx_ncpu = ngx_freebsd_hw_ncpu / 2;
                    209: 
                    210:     } else {
                    211:         ngx_ncpu = ngx_freebsd_hw_ncpu;
                    212:     }
                    213: 
                    214:     if (version < 600008 && ngx_freebsd_kern_ipc_somaxconn > 32767) {
                    215:         ngx_log_error(NGX_LOG_ALERT, log, 0,
                    216:                       "sysctl kern.ipc.somaxconn must be less than 32768");
                    217:         return NGX_ERROR;
                    218:     }
                    219: 
                    220:     ngx_tcp_nodelay_and_tcp_nopush = 1;
                    221: 
                    222:     ngx_os_io = ngx_freebsd_io;
                    223: 
                    224:     return NGX_OK;
                    225: }
                    226: 
                    227: 
                    228: void
                    229: ngx_os_specific_status(ngx_log_t *log)
                    230: {
                    231:     u_long      value;
                    232:     ngx_uint_t  i;
                    233: 
                    234:     ngx_log_error(NGX_LOG_NOTICE, log, 0, "OS: %s %s",
                    235:                   ngx_freebsd_kern_ostype, ngx_freebsd_kern_osrelease);
                    236: 
                    237: #ifdef __DragonFly_version
                    238:     ngx_log_error(NGX_LOG_NOTICE, log, 0,
                    239:                   "kern.osreldate: %d, built on %d",
                    240:                   ngx_freebsd_kern_osreldate, __DragonFly_version);
                    241: #else
                    242:     ngx_log_error(NGX_LOG_NOTICE, log, 0,
                    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: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>