Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.13.12 ]​[ nginx-1.12.2 ]​

0001 
0002 /*
0003  * Copyright (C) Igor Sysoev
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 
0008 #include <ngx_config.h>
0009 #include <ngx_core.h>
0010 #include <ngx_http.h>
0011 
0012 
0013 typedef struct {
0014     size_t      sbrk_size;
0015 } ngx_http_degradation_main_conf_t;
0016 
0017 
0018 typedef struct {
0019     ngx_uint_t  degrade;
0020 } ngx_http_degradation_loc_conf_t;
0021 
0022 
0023 static ngx_conf_enum_t  ngx_http_degrade[] = {
0024     { ngx_string("204"), 204 },
0025     { ngx_string("444"), 444 },
0026     { ngx_null_string, 0 }
0027 };
0028 
0029 
0030 static void *ngx_http_degradation_create_main_conf(ngx_conf_t *cf);
0031 static void *ngx_http_degradation_create_loc_conf(ngx_conf_t *cf);
0032 static char *ngx_http_degradation_merge_loc_conf(ngx_conf_t *cf, void *parent,
0033     void *child);
0034 static char *ngx_http_degradation(ngx_conf_t *cf, ngx_command_t *cmd,
0035     void *conf);
0036 static ngx_int_t ngx_http_degradation_init(ngx_conf_t *cf);
0037 
0038 
0039 static ngx_command_t  ngx_http_degradation_commands[] = {
0040 
0041     { ngx_string("degradation"),
0042       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
0043       ngx_http_degradation,
0044       NGX_HTTP_MAIN_CONF_OFFSET,
0045       0,
0046       NULL },
0047 
0048     { ngx_string("degrade"),
0049       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0050       ngx_conf_set_enum_slot,
0051       NGX_HTTP_LOC_CONF_OFFSET,
0052       offsetof(ngx_http_degradation_loc_conf_t, degrade),
0053       &ngx_http_degrade },
0054 
0055       ngx_null_command
0056 };
0057 
0058 
0059 static ngx_http_module_t  ngx_http_degradation_module_ctx = {
0060     NULL,                                  /* preconfiguration */
0061     ngx_http_degradation_init,             /* postconfiguration */
0062 
0063     ngx_http_degradation_create_main_conf, /* create main configuration */
0064     NULL,                                  /* init main configuration */
0065 
0066     NULL,                                  /* create server configuration */
0067     NULL,                                  /* merge server configuration */
0068 
0069     ngx_http_degradation_create_loc_conf,  /* create location configuration */
0070     ngx_http_degradation_merge_loc_conf    /* merge location configuration */
0071 };
0072 
0073 
0074 ngx_module_t  ngx_http_degradation_module = {
0075     NGX_MODULE_V1,
0076     &ngx_http_degradation_module_ctx,      /* module context */
0077     ngx_http_degradation_commands,         /* module directives */
0078     NGX_HTTP_MODULE,                       /* module type */
0079     NULL,                                  /* init master */
0080     NULL,                                  /* init module */
0081     NULL,                                  /* init process */
0082     NULL,                                  /* init thread */
0083     NULL,                                  /* exit thread */
0084     NULL,                                  /* exit process */
0085     NULL,                                  /* exit master */
0086     NGX_MODULE_V1_PADDING
0087 };
0088 
0089 
0090 static ngx_int_t
0091 ngx_http_degradation_handler(ngx_http_request_t *r)
0092 {
0093     ngx_http_degradation_loc_conf_t  *dlcf;
0094 
0095     dlcf = ngx_http_get_module_loc_conf(r, ngx_http_degradation_module);
0096 
0097     if (dlcf->degrade && ngx_http_degraded(r)) {
0098         return dlcf->degrade;
0099     }
0100 
0101     return NGX_DECLINED;
0102 }
0103 
0104 
0105 ngx_uint_t
0106 ngx_http_degraded(ngx_http_request_t *r)
0107 {
0108     time_t                             now;
0109     ngx_uint_t                         log;
0110     static size_t                      sbrk_size;
0111     static time_t                      sbrk_time;
0112     ngx_http_degradation_main_conf_t  *dmcf;
0113 
0114     dmcf = ngx_http_get_module_main_conf(r, ngx_http_degradation_module);
0115 
0116     if (dmcf->sbrk_size) {
0117 
0118         log = 0;
0119         now = ngx_time();
0120 
0121         /* lock mutex */
0122 
0123         if (now != sbrk_time) {
0124 
0125             /*
0126              * ELF/i386 is loaded at 0x08000000, 128M
0127              * ELF/amd64 is loaded at 0x00400000, 4M
0128              *
0129              * use a function address to subtract the loading address
0130              */
0131 
0132             sbrk_size = (size_t) sbrk(0) - ((uintptr_t) ngx_palloc & ~0x3FFFFF);
0133             sbrk_time = now;
0134             log = 1;
0135         }
0136 
0137         /* unlock mutex */
0138 
0139         if (sbrk_size >= dmcf->sbrk_size) {
0140             if (log) {
0141                 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
0142                               "degradation sbrk:%uzM",
0143                               sbrk_size / (1024 * 1024));
0144             }
0145 
0146             return 1;
0147         }
0148     }
0149 
0150     return 0;
0151 }
0152 
0153 
0154 static void *
0155 ngx_http_degradation_create_main_conf(ngx_conf_t *cf)
0156 {
0157     ngx_http_degradation_main_conf_t  *dmcf;
0158 
0159     dmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_degradation_main_conf_t));
0160     if (dmcf == NULL) {
0161         return NULL;
0162     }
0163 
0164     return dmcf;
0165 }
0166 
0167 
0168 static void *
0169 ngx_http_degradation_create_loc_conf(ngx_conf_t *cf)
0170 {
0171     ngx_http_degradation_loc_conf_t  *conf;
0172 
0173     conf = ngx_palloc(cf->pool, sizeof(ngx_http_degradation_loc_conf_t));
0174     if (conf == NULL) {
0175         return NULL;
0176     }
0177 
0178     conf->degrade = NGX_CONF_UNSET_UINT;
0179 
0180     return conf;
0181 }
0182 
0183 
0184 static char *
0185 ngx_http_degradation_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
0186 {
0187     ngx_http_degradation_loc_conf_t  *prev = parent;
0188     ngx_http_degradation_loc_conf_t  *conf = child;
0189 
0190     ngx_conf_merge_uint_value(conf->degrade, prev->degrade, 0);
0191 
0192     return NGX_CONF_OK;
0193 }
0194 
0195 
0196 static char *
0197 ngx_http_degradation(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0198 {
0199     ngx_http_degradation_main_conf_t  *dmcf = conf;
0200 
0201     ngx_str_t  *value, s;
0202 
0203     value = cf->args->elts;
0204 
0205     if (ngx_strncmp(value[1].data, "sbrk=", 5) == 0) {
0206 
0207         s.len = value[1].len - 5;
0208         s.data = value[1].data + 5;
0209 
0210         dmcf->sbrk_size = ngx_parse_size(&s);
0211         if (dmcf->sbrk_size == (size_t) NGX_ERROR) {
0212             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0213                                "invalid sbrk size \"%V\"", &value[1]);
0214             return NGX_CONF_ERROR;
0215         }
0216 
0217         return NGX_CONF_OK;
0218     }
0219 
0220     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0221                        "invalid parameter \"%V\"", &value[1]);
0222 
0223     return NGX_CONF_ERROR;
0224 }
0225 
0226 
0227 static ngx_int_t
0228 ngx_http_degradation_init(ngx_conf_t *cf)
0229 {
0230     ngx_http_handler_pt        *h;
0231     ngx_http_core_main_conf_t  *cmcf;
0232 
0233     cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
0234 
0235     h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers);
0236     if (h == NULL) {
0237         return NGX_ERROR;
0238     }
0239 
0240     *h = ngx_http_degradation_handler;
0241 
0242     return NGX_OK;
0243 }