changeset 7151:9ef704d8563a

Core: free shared memory zones only after reconfiguration. This is what usually happens for zones no longer used in the new configuration, but zones where size or tag were changed were freed when creating new memory zones. If reconfiguration failed (for example, due to a conflicting listening socket), this resulted in a segmentation fault in the master process. Reported by Zhihua Cao, http://mailman.nginx.org/pipermail/nginx-devel/2017-October/010536.html.
author Maxim Dounin <mdounin@mdounin.ru>
date Tue, 17 Oct 2017 19:52:16 +0300
parents d87f29d764ce
children 3b635e8fd499
files src/core/ngx_cycle.c
diffstat 1 files changed, 17 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -470,8 +470,6 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
                 goto shm_zone_found;
             }
 
-            ngx_shm_free(&oshm_zone[n].shm);
-
             break;
         }
 
@@ -662,14 +660,26 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
                 n = 0;
             }
 
-            if (oshm_zone[i].shm.name.len == shm_zone[n].shm.name.len
-                && ngx_strncmp(oshm_zone[i].shm.name.data,
-                               shm_zone[n].shm.name.data,
-                               oshm_zone[i].shm.name.len)
-                == 0)
+            if (oshm_zone[i].shm.name.len != shm_zone[n].shm.name.len) {
+                continue;
+            }
+
+            if (ngx_strncmp(oshm_zone[i].shm.name.data,
+                            shm_zone[n].shm.name.data,
+                            oshm_zone[i].shm.name.len)
+                != 0)
+            {
+                continue;
+            }
+
+            if (oshm_zone[i].tag == shm_zone[n].tag
+                && oshm_zone[i].shm.size == shm_zone[n].shm.size
+                && !oshm_zone[i].noreuse)
             {
                 goto live_shm_zone;
             }
+
+            break;
         }
 
         ngx_shm_free(&oshm_zone[i].shm);