3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
8 #include <ngx_config.h>
15 } ngx_http_degradation_main_conf_t
;
20 } ngx_http_degradation_loc_conf_t
;
23 static ngx_conf_enum_t ngx_http_degrade
[] = {
24 { ngx_string("204"), 204 },
25 { ngx_string("444"), 444 },
26 { ngx_null_string
, 0 }
30 static void *ngx_http_degradation_create_main_conf(ngx_conf_t
*cf
);
31 static void *ngx_http_degradation_create_loc_conf(ngx_conf_t
*cf
);
32 static char *ngx_http_degradation_merge_loc_conf(ngx_conf_t
*cf
, void *parent
,
34 static char *ngx_http_degradation(ngx_conf_t
*cf
, ngx_command_t
*cmd
,
36 static ngx_int_t
ngx_http_degradation_init(ngx_conf_t
*cf
);
39 static ngx_command_t ngx_http_degradation_commands
[] = {
41 { ngx_string("degradation"),
42 NGX_HTTP_MAIN_CONF
|NGX_CONF_TAKE1
,
44 NGX_HTTP_MAIN_CONF_OFFSET
,
48 { ngx_string("degrade"),
49 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_TAKE1
,
50 ngx_conf_set_enum_slot
,
51 NGX_HTTP_LOC_CONF_OFFSET
,
52 offsetof(ngx_http_degradation_loc_conf_t
, degrade
),
59 static ngx_http_module_t ngx_http_degradation_module_ctx
= {
60 NULL
, /* preconfiguration */
61 ngx_http_degradation_init
, /* postconfiguration */
63 ngx_http_degradation_create_main_conf
, /* create main configuration */
64 NULL
, /* init main configuration */
66 NULL
, /* create server configuration */
67 NULL
, /* merge server configuration */
69 ngx_http_degradation_create_loc_conf
, /* create location configuration */
70 ngx_http_degradation_merge_loc_conf
/* merge location configuration */
74 ngx_module_t ngx_http_degradation_module
= {
76 &ngx_http_degradation_module_ctx
, /* module context */
77 ngx_http_degradation_commands
, /* module directives */
78 NGX_HTTP_MODULE
, /* module type */
79 NULL
, /* init master */
80 NULL
, /* init module */
81 NULL
, /* init process */
82 NULL
, /* init thread */
83 NULL
, /* exit thread */
84 NULL
, /* exit process */
85 NULL
, /* exit master */
91 ngx_http_degradation_handler(ngx_http_request_t
*r
)
93 ngx_http_degradation_loc_conf_t
*dlcf
;
95 dlcf
= ngx_http_get_module_loc_conf(r
, ngx_http_degradation_module
);
97 if (dlcf
->degrade
&& ngx_http_degraded(r
)) {
106 ngx_http_degraded(ngx_http_request_t
*r
)
110 static size_t sbrk_size
;
111 static time_t sbrk_time
;
112 ngx_http_degradation_main_conf_t
*dmcf
;
114 dmcf
= ngx_http_get_module_main_conf(r
, ngx_http_degradation_module
);
116 if (dmcf
->sbrk_size
) {
123 if (now
!= sbrk_time
) {
126 * ELF/i386 is loaded at 0x08000000, 128M
127 * ELF/amd64 is loaded at 0x00400000, 4M
129 * use a function address to subtract the loading address
132 sbrk_size
= (size_t) sbrk(0) - ((uintptr_t) ngx_palloc
& ~0x3FFFFF);
139 if (sbrk_size
>= dmcf
->sbrk_size
) {
141 ngx_log_error(NGX_LOG_NOTICE
, r
->connection
->log
, 0,
142 "degradation sbrk:%uzM",
143 sbrk_size
/ (1024 * 1024));
155 ngx_http_degradation_create_main_conf(ngx_conf_t
*cf
)
157 ngx_http_degradation_main_conf_t
*dmcf
;
159 dmcf
= ngx_pcalloc(cf
->pool
, sizeof(ngx_http_degradation_main_conf_t
));
169 ngx_http_degradation_create_loc_conf(ngx_conf_t
*cf
)
171 ngx_http_degradation_loc_conf_t
*conf
;
173 conf
= ngx_palloc(cf
->pool
, sizeof(ngx_http_degradation_loc_conf_t
));
178 conf
->degrade
= NGX_CONF_UNSET_UINT
;
185 ngx_http_degradation_merge_loc_conf(ngx_conf_t
*cf
, void *parent
, void *child
)
187 ngx_http_degradation_loc_conf_t
*prev
= parent
;
188 ngx_http_degradation_loc_conf_t
*conf
= child
;
190 ngx_conf_merge_uint_value(conf
->degrade
, prev
->degrade
, 0);
197 ngx_http_degradation(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
199 ngx_http_degradation_main_conf_t
*dmcf
= conf
;
203 value
= cf
->args
->elts
;
205 if (ngx_strncmp(value
[1].data
, "sbrk=", 5) == 0) {
207 s
.len
= value
[1].len
- 5;
208 s
.data
= value
[1].data
+ 5;
210 dmcf
->sbrk_size
= ngx_parse_size(&s
);
211 if (dmcf
->sbrk_size
== (size_t) NGX_ERROR
) {
212 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
213 "invalid sbrk size \"%V\"", &value
[1]);
214 return NGX_CONF_ERROR
;
220 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
221 "invalid parameter \"%V\"", &value
[1]);
223 return NGX_CONF_ERROR
;
228 ngx_http_degradation_init(ngx_conf_t
*cf
)
230 ngx_http_handler_pt
*h
;
231 ngx_http_core_main_conf_t
*cmcf
;
233 cmcf
= ngx_http_conf_get_module_main_conf(cf
, ngx_http_core_module
);
235 h
= ngx_array_push(&cmcf
->phases
[NGX_HTTP_PREACCESS_PHASE
].handlers
);
240 *h
= ngx_http_degradation_handler
;