src/os/unix/ngx_freebsd_init.c - nginx-1.7.10

Global variables defined

Data types defined

Functions defined

Source code


  1. /*
  2. * Copyright (C) Igor Sysoev
  3. * Copyright (C) Nginx, Inc.
  4. */


  5. #include <ngx_config.h>
  6. #include <ngx_core.h>


  7. /* FreeBSD 3.0 at least */
  8. char    ngx_freebsd_kern_ostype[16];
  9. char    ngx_freebsd_kern_osrelease[128];
  10. int     ngx_freebsd_kern_osreldate;
  11. int     ngx_freebsd_hw_ncpu;
  12. int     ngx_freebsd_kern_ipc_somaxconn;
  13. u_long  ngx_freebsd_net_inet_tcp_sendspace;

  14. /* FreeBSD 4.9 */
  15. int     ngx_freebsd_machdep_hlt_logical_cpus;


  16. ngx_uint_t  ngx_freebsd_sendfile_nbytes_bug;
  17. ngx_uint_t  ngx_freebsd_use_tcp_nopush;

  18. ngx_uint_t  ngx_debug_malloc;


  19. static ngx_os_io_t ngx_freebsd_io = {
  20.     ngx_unix_recv,
  21.     ngx_readv_chain,
  22.     ngx_udp_unix_recv,
  23.     ngx_unix_send,
  24. #if (NGX_HAVE_SENDFILE)
  25.     ngx_freebsd_sendfile_chain,
  26.     NGX_IO_SENDFILE
  27. #else
  28.     ngx_writev_chain,
  29.     0
  30. #endif
  31. };


  32. typedef struct {
  33.     char        *name;
  34.     void        *value;
  35.     size_t       size;
  36.     ngx_uint_t   exists;
  37. } sysctl_t;


  38. sysctl_t sysctls[] = {
  39.     { "hw.ncpu",
  40.       &ngx_freebsd_hw_ncpu,
  41.       sizeof(ngx_freebsd_hw_ncpu), 0 },

  42.     { "machdep.hlt_logical_cpus",
  43.       &ngx_freebsd_machdep_hlt_logical_cpus,
  44.       sizeof(ngx_freebsd_machdep_hlt_logical_cpus), 0 },

  45.     { "net.inet.tcp.sendspace",
  46.       &ngx_freebsd_net_inet_tcp_sendspace,
  47.       sizeof(ngx_freebsd_net_inet_tcp_sendspace), 0 },

  48.     { "kern.ipc.somaxconn",
  49.       &ngx_freebsd_kern_ipc_somaxconn,
  50.       sizeof(ngx_freebsd_kern_ipc_somaxconn), 0 },

  51.     { NULL, NULL, 0, 0 }
  52. };


  53. void
  54. ngx_debug_init(void)
  55. {
  56. #if (NGX_DEBUG_MALLOC)

  57. #if __FreeBSD_version >= 500014 && __FreeBSD_version < 1000011
  58.     _malloc_options = "J";
  59. #elif __FreeBSD_version < 500014
  60.     malloc_options = "J";
  61. #endif

  62.     ngx_debug_malloc = 1;

  63. #else
  64.     char  *mo;

  65.     mo = getenv("MALLOC_OPTIONS");

  66.     if (mo && ngx_strchr(mo, 'J')) {
  67.         ngx_debug_malloc = 1;
  68.     }
  69. #endif
  70. }


  71. ngx_int_t
  72. ngx_os_specific_init(ngx_log_t *log)
  73. {
  74.     int         version;
  75.     size_t      size;
  76.     ngx_err_t   err;
  77.     ngx_uint_t  i;

  78.     size = sizeof(ngx_freebsd_kern_ostype);
  79.     if (sysctlbyname("kern.ostype",
  80.                      ngx_freebsd_kern_ostype, &size, NULL, 0) == -1) {
  81.         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
  82.                       "sysctlbyname(kern.ostype) failed");

  83.         if (ngx_errno != NGX_ENOMEM) {
  84.             return NGX_ERROR;
  85.         }

  86.         ngx_freebsd_kern_ostype[size - 1] = '\0';
  87.     }

  88.     size = sizeof(ngx_freebsd_kern_osrelease);
  89.     if (sysctlbyname("kern.osrelease",
  90.                      ngx_freebsd_kern_osrelease, &size, NULL, 0) == -1) {
  91.         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
  92.                       "sysctlbyname(kern.osrelease) failed");

  93.         if (ngx_errno != NGX_ENOMEM) {
  94.             return NGX_ERROR;
  95.         }

  96.         ngx_freebsd_kern_osrelease[size - 1] = '\0';
  97.     }


  98.     size = sizeof(int);
  99.     if (sysctlbyname("kern.osreldate",
  100.                      &ngx_freebsd_kern_osreldate, &size, NULL, 0) == -1) {
  101.         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
  102.                       "sysctlbyname(kern.osreldate) failed");
  103.         return NGX_ERROR;
  104.     }

  105.     version = ngx_freebsd_kern_osreldate;


  106. #if (NGX_HAVE_SENDFILE)

  107.     /*
  108.      * The determination of the sendfile() "nbytes bug" is complex enough.
  109.      * There are two sendfile() syscalls: a new #393 has no bug while
  110.      * an old #336 has the bug in some versions and has not in others.
  111.      * Besides libc_r wrapper also emulates the bug in some versions.
  112.      * There is no way to say exactly if syscall #336 in FreeBSD circa 4.6
  113.      * has the bug.  We use the algorithm that is correct at least for
  114.      * RELEASEs and for syscalls only (not libc_r wrapper).
  115.      *
  116.      * 4.6.1-RELEASE and below have the bug
  117.      * 4.6.2-RELEASE and above have the new syscall
  118.      *
  119.      * We detect the new sendfile() syscall available at the compile time
  120.      * to allow an old binary to run correctly on an updated FreeBSD system.
  121.      */

  122. #if (__FreeBSD__ == 4 && __FreeBSD_version >= 460102) \
  123.     || __FreeBSD_version == 460002 || __FreeBSD_version >= 500039

  124.     /* a new syscall without the bug */

  125.     ngx_freebsd_sendfile_nbytes_bug = 0;

  126. #else

  127.     /* an old syscall that may have the bug */

  128.     ngx_freebsd_sendfile_nbytes_bug = 1;

  129. #endif

  130. #endif /* NGX_HAVE_SENDFILE */


  131.     if ((version < 500000 && version >= 440003) || version >= 500017) {
  132.         ngx_freebsd_use_tcp_nopush = 1;
  133.     }


  134.     for (i = 0; sysctls[i].name; i++) {
  135.         size = sysctls[i].size;

  136.         if (sysctlbyname(sysctls[i].name, sysctls[i].value, &size, NULL, 0)
  137.             == 0)
  138.         {
  139.             sysctls[i].exists = 1;
  140.             continue;
  141.         }

  142.         err = ngx_errno;

  143.         if (err == NGX_ENOENT) {
  144.             continue;
  145.         }

  146.         ngx_log_error(NGX_LOG_ALERT, log, err,
  147.                       "sysctlbyname(%s) failed", sysctls[i].name);
  148.         return NGX_ERROR;
  149.     }

  150.     if (ngx_freebsd_machdep_hlt_logical_cpus) {
  151.         ngx_ncpu = ngx_freebsd_hw_ncpu / 2;

  152.     } else {
  153.         ngx_ncpu = ngx_freebsd_hw_ncpu;
  154.     }

  155.     if (version < 600008 && ngx_freebsd_kern_ipc_somaxconn > 32767) {
  156.         ngx_log_error(NGX_LOG_ALERT, log, 0,
  157.                       "sysctl kern.ipc.somaxconn must be less than 32768");
  158.         return NGX_ERROR;
  159.     }

  160.     ngx_tcp_nodelay_and_tcp_nopush = 1;

  161.     ngx_os_io = ngx_freebsd_io;

  162.     return NGX_OK;
  163. }


  164. void
  165. ngx_os_specific_status(ngx_log_t *log)
  166. {
  167.     u_long      value;
  168.     ngx_uint_t  i;

  169.     ngx_log_error(NGX_LOG_NOTICE, log, 0, "OS: %s %s",
  170.                   ngx_freebsd_kern_ostype, ngx_freebsd_kern_osrelease);

  171. #ifdef __DragonFly_version
  172.     ngx_log_error(NGX_LOG_NOTICE, log, 0,
  173.                   "kern.osreldate: %d, built on %d",
  174.                   ngx_freebsd_kern_osreldate, __DragonFly_version);
  175. #else
  176.     ngx_log_error(NGX_LOG_NOTICE, log, 0,
  177.                   "kern.osreldate: %d, built on %d",
  178.                   ngx_freebsd_kern_osreldate, __FreeBSD_version);
  179. #endif

  180.     for (i = 0; sysctls[i].name; i++) {
  181.         if (sysctls[i].exists) {
  182.             if (sysctls[i].size == sizeof(long)) {
  183.                 value = *(long *) sysctls[i].value;

  184.             } else {
  185.                 value = *(int *) sysctls[i].value;
  186.             }

  187.             ngx_log_error(NGX_LOG_NOTICE, log, 0, "%s: %l",
  188.                           sysctls[i].name, value);
  189.         }
  190.     }
  191. }