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) Ruslan Ermilov
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 static char *ngx_http_upstream_zone(ngx_conf_t *cf, ngx_command_t *cmd,
0014     void *conf);
0015 static ngx_int_t ngx_http_upstream_init_zone(ngx_shm_zone_t *shm_zone,
0016     void *data);
0017 static ngx_http_upstream_rr_peers_t *ngx_http_upstream_zone_copy_peers(
0018     ngx_slab_pool_t *shpool, ngx_http_upstream_srv_conf_t *uscf);
0019 
0020 
0021 static ngx_command_t  ngx_http_upstream_zone_commands[] = {
0022 
0023     { ngx_string("zone"),
0024       NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12,
0025       ngx_http_upstream_zone,
0026       0,
0027       0,
0028       NULL },
0029 
0030       ngx_null_command
0031 };
0032 
0033 
0034 static ngx_http_module_t  ngx_http_upstream_zone_module_ctx = {
0035     NULL,                                  /* preconfiguration */
0036     NULL,                                  /* postconfiguration */
0037 
0038     NULL,                                  /* create main configuration */
0039     NULL,                                  /* init main configuration */
0040 
0041     NULL,                                  /* create server configuration */
0042     NULL,                                  /* merge server configuration */
0043 
0044     NULL,                                  /* create location configuration */
0045     NULL                                   /* merge location configuration */
0046 };
0047 
0048 
0049 ngx_module_t  ngx_http_upstream_zone_module = {
0050     NGX_MODULE_V1,
0051     &ngx_http_upstream_zone_module_ctx,    /* module context */
0052     ngx_http_upstream_zone_commands,       /* module directives */
0053     NGX_HTTP_MODULE,                       /* module type */
0054     NULL,                                  /* init master */
0055     NULL,                                  /* init module */
0056     NULL,                                  /* init process */
0057     NULL,                                  /* init thread */
0058     NULL,                                  /* exit thread */
0059     NULL,                                  /* exit process */
0060     NULL,                                  /* exit master */
0061     NGX_MODULE_V1_PADDING
0062 };
0063 
0064 
0065 static char *
0066 ngx_http_upstream_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0067 {
0068     ssize_t                         size;
0069     ngx_str_t                      *value;
0070     ngx_http_upstream_srv_conf_t   *uscf;
0071     ngx_http_upstream_main_conf_t  *umcf;
0072 
0073     uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
0074     umcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_upstream_module);
0075 
0076     value = cf->args->elts;
0077 
0078     if (!value[1].len) {
0079         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0080                            "invalid zone name \"%V\"", &value[1]);
0081         return NGX_CONF_ERROR;
0082     }
0083 
0084     if (cf->args->nelts == 3) {
0085         size = ngx_parse_size(&value[2]);
0086 
0087         if (size == NGX_ERROR) {
0088             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0089                                "invalid zone size \"%V\"", &value[2]);
0090             return NGX_CONF_ERROR;
0091         }
0092 
0093         if (size < (ssize_t) (8 * ngx_pagesize)) {
0094             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0095                                "zone \"%V\" is too small", &value[1]);
0096             return NGX_CONF_ERROR;
0097         }
0098 
0099     } else {
0100         size = 0;
0101     }
0102 
0103     uscf->shm_zone = ngx_shared_memory_add(cf, &value[1], size,
0104                                            &ngx_http_upstream_module);
0105     if (uscf->shm_zone == NULL) {
0106         return NGX_CONF_ERROR;
0107     }
0108 
0109     uscf->shm_zone->init = ngx_http_upstream_init_zone;
0110     uscf->shm_zone->data = umcf;
0111 
0112     uscf->shm_zone->noreuse = 1;
0113 
0114     return NGX_CONF_OK;
0115 }
0116 
0117 
0118 static ngx_int_t
0119 ngx_http_upstream_init_zone(ngx_shm_zone_t *shm_zone, void *data)
0120 {
0121     size_t                          len;
0122     ngx_uint_t                      i;
0123     ngx_slab_pool_t                *shpool;
0124     ngx_http_upstream_rr_peers_t   *peers, **peersp;
0125     ngx_http_upstream_srv_conf_t   *uscf, **uscfp;
0126     ngx_http_upstream_main_conf_t  *umcf;
0127 
0128     shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
0129     umcf = shm_zone->data;
0130     uscfp = umcf->upstreams.elts;
0131 
0132     if (shm_zone->shm.exists) {
0133         peers = shpool->data;
0134 
0135         for (i = 0; i < umcf->upstreams.nelts; i++) {
0136             uscf = uscfp[i];
0137 
0138             if (uscf->shm_zone != shm_zone) {
0139                 continue;
0140             }
0141 
0142             uscf->peer.data = peers;
0143             peers = peers->zone_next;
0144         }
0145 
0146         return NGX_OK;
0147     }
0148 
0149     len = sizeof(" in upstream zone \"\"") + shm_zone->shm.name.len;
0150 
0151     shpool->log_ctx = ngx_slab_alloc(shpool, len);
0152     if (shpool->log_ctx == NULL) {
0153         return NGX_ERROR;
0154     }
0155 
0156     ngx_sprintf(shpool->log_ctx, " in upstream zone \"%V\"%Z",
0157                 &shm_zone->shm.name);
0158 
0159 
0160     /* copy peers to shared memory */
0161 
0162     peersp = (ngx_http_upstream_rr_peers_t **) (void *) &shpool->data;
0163 
0164     for (i = 0; i < umcf->upstreams.nelts; i++) {
0165         uscf = uscfp[i];
0166 
0167         if (uscf->shm_zone != shm_zone) {
0168             continue;
0169         }
0170 
0171         peers = ngx_http_upstream_zone_copy_peers(shpool, uscf);
0172         if (peers == NULL) {
0173             return NGX_ERROR;
0174         }
0175 
0176         *peersp = peers;
0177         peersp = &peers->zone_next;
0178     }
0179 
0180     return NGX_OK;
0181 }
0182 
0183 
0184 static ngx_http_upstream_rr_peers_t *
0185 ngx_http_upstream_zone_copy_peers(ngx_slab_pool_t *shpool,
0186     ngx_http_upstream_srv_conf_t *uscf)
0187 {
0188     ngx_http_upstream_rr_peer_t   *peer, **peerp;
0189     ngx_http_upstream_rr_peers_t  *peers, *backup;
0190 
0191     peers = ngx_slab_alloc(shpool, sizeof(ngx_http_upstream_rr_peers_t));
0192     if (peers == NULL) {
0193         return NULL;
0194     }
0195 
0196     ngx_memcpy(peers, uscf->peer.data, sizeof(ngx_http_upstream_rr_peers_t));
0197 
0198     peers->shpool = shpool;
0199 
0200     for (peerp = &peers->peer; *peerp; peerp = &peer->next) {
0201         /* pool is unlocked */
0202         peer = ngx_slab_calloc_locked(shpool,
0203                                       sizeof(ngx_http_upstream_rr_peer_t));
0204         if (peer == NULL) {
0205             return NULL;
0206         }
0207 
0208         ngx_memcpy(peer, *peerp, sizeof(ngx_http_upstream_rr_peer_t));
0209 
0210         *peerp = peer;
0211     }
0212 
0213     if (peers->next == NULL) {
0214         goto done;
0215     }
0216 
0217     backup = ngx_slab_alloc(shpool, sizeof(ngx_http_upstream_rr_peers_t));
0218     if (backup == NULL) {
0219         return NULL;
0220     }
0221 
0222     ngx_memcpy(backup, peers->next, sizeof(ngx_http_upstream_rr_peers_t));
0223 
0224     backup->shpool = shpool;
0225 
0226     for (peerp = &backup->peer; *peerp; peerp = &peer->next) {
0227         /* pool is unlocked */
0228         peer = ngx_slab_calloc_locked(shpool,
0229                                       sizeof(ngx_http_upstream_rr_peer_t));
0230         if (peer == NULL) {
0231             return NULL;
0232         }
0233 
0234         ngx_memcpy(peer, *peerp, sizeof(ngx_http_upstream_rr_peer_t));
0235 
0236         *peerp = peer;
0237     }
0238 
0239     peers->next = backup;
0240 
0241 done:
0242 
0243     uscf->peer.data = peers;
0244 
0245     return peers;
0246 }