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