Index: modules/slotmem/mod_slotmem_shm.c =================================================================== --- modules/slotmem/mod_slotmem_shm.c (revision 1830524) +++ modules/slotmem/mod_slotmem_shm.c (working copy) @@ -26,6 +26,7 @@ #include "httpd.h" #include "http_main.h" #include "http_core.h" +#include "ap_mpm.h" #define AP_SLOTMEM_IS_PREGRAB(t) (t->desc->type & AP_SLOTMEM_TYPE_PREGRAB) #define AP_SLOTMEM_IS_PERSIST(t) (t->desc->type & AP_SLOTMEM_TYPE_PERSIST) @@ -42,7 +43,8 @@ typedef struct { #define AP_UNSIGNEDINT_OFFSET (APR_ALIGN_DEFAULT(sizeof(unsigned int))) struct ap_slotmem_instance_t { - char *name; /* file based SHM path/name */ + char *name; /* file based SHM name (immutable) */ + char *fname; /* file based SHM path/name */ char *pname; /* persisted file path/name */ int fbased; /* filebased? */ void *shm; /* ptr to memory segment (apr_shm_t *) */ @@ -320,7 +322,7 @@ static apr_status_t cleanup_slotmem(void *is_start * unlink, thus call destroy() first. */ apr_shm_destroy(mem->shm); - apr_shm_remove(mem->name, mem->pool); + apr_shm_remove(mem->fname, mem->pool); } } @@ -368,19 +370,19 @@ static int check_slotmem(ap_slotmem_instance_t *me /* check size */ if (apr_shm_size_get(mem->shm) != size) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(02599) - "existing shared memory for %s could not be used " + ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(02599) + "existing shared memory for %s could not be reused " "(failed size check)", - mem->name); + mem->fname); return 0; } desc = apr_shm_baseaddr_get(mem->shm); if (desc->size != item_size || desc->num != item_num) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(02600) - "existing shared memory for %s could not be used " + ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(02600) + "existing shared memory for %s could not be reused " "(failed contents check)", - mem->name); + mem->fname); return 0; } @@ -387,6 +389,19 @@ static int check_slotmem(ap_slotmem_instance_t *me return 1; } +static apr_status_t slotmem_attach_shm(apr_shm_t **shm, const char **fname, + int generation, apr_pool_t *pool) +{ + for (; generation > 0; --generation) { + const char *gname = apr_psprintf(pool, "%s.%i", *fname, generation); + if (apr_shm_attach(shm, gname, pool) == APR_SUCCESS) { + *fname = gname; + return APR_SUCCESS; + } + } + return apr_shm_attach(shm, *fname, pool); +} + static apr_status_t slotmem_create(ap_slotmem_instance_t **new, const char *name, apr_size_t item_size, unsigned int item_num, @@ -404,10 +419,12 @@ static apr_status_t slotmem_create(ap_slotmem_inst apr_size_t size = AP_SLOTMEM_OFFSET + AP_UNSIGNEDINT_OFFSET + (item_num * sizeof(char)) + basesize; int persist = (type & AP_SLOTMEM_TYPE_PERSIST) != 0; + int generation = 0; apr_status_t rv; apr_pool_t *p; *new = NULL; + ap_mpm_query(AP_MPMQ_GENERATION, &generation); if (slotmem_filenames(pool, name, &fname, persist ? &pname : NULL)) { /* first try to attach to existing slotmem */ @@ -414,10 +431,20 @@ static apr_status_t slotmem_create(ap_slotmem_inst if (next) { ap_slotmem_instance_t *prev = NULL; for (;;) { - if (strcmp(next->name, fname) == 0) { + if (strcmp(next->name, name) == 0) { *new = next; /* either returned here or reused finally */ if (!check_slotmem(next, size, item_size, item_num)) { + /* Can't reuse this SHM, a new one is needed with its + * own filename (including generation number) because + * the previous one may still be used by the previous + * generation. Persisted file (if any) can't be reused + * either. + */ apr_shm_destroy(next->shm); + apr_shm_remove(next->fname, pool); + fname = apr_psprintf(pool, "%s.%i", fname, generation); + persist = 0; + next = next->next; if (prev) { prev->next = next; @@ -463,7 +490,7 @@ static apr_status_t slotmem_create(ap_slotmem_inst * parent exist in the children already; only attach them. */ if (is_child_process()) { - rv = apr_shm_attach(&shm, fname, gpool); + rv = slotmem_attach_shm(&shm, &fname, generation, pool); } else { apr_shm_remove(fname, pool); @@ -516,10 +543,11 @@ static apr_status_t slotmem_create(ap_slotmem_inst res = *new; if (res == NULL) { res = apr_pcalloc(p, sizeof(ap_slotmem_instance_t)); - res->name = apr_pstrdup(p, fname); + res->name = apr_pstrdup(p, name); res->pname = apr_pstrdup(p, pname); *new = res; } + res->fname = apr_pstrdup(p, fname); res->fbased = fbased; res->shm = shm; res->persist = (void *)ptr; @@ -554,10 +582,14 @@ static apr_status_t slotmem_attach(ap_slotmem_inst ap_slotmem_instance_t *res; ap_slotmem_instance_t *next = globallistmem; sharedslotdesc_t *desc; + int generation = 0; const char *fname; apr_shm_t *shm; apr_status_t rv; + *new = NULL; + ap_mpm_query(AP_MPMQ_GENERATION, &generation); + if (!slotmem_filenames(pool, name, &fname, NULL)) { return APR_ENOSHMAVAIL; } @@ -568,7 +600,7 @@ static apr_status_t slotmem_attach(ap_slotmem_inst /* first try to attach to existing slotmem */ if (next) { for (;;) { - if (strcmp(next->name, fname) == 0) { + if (strcmp(next->name, name) == 0) { /* we already have it */ *new = next; *item_size = next->desc->size; @@ -587,7 +619,7 @@ static apr_status_t slotmem_attach(ap_slotmem_inst } /* next try to attach to existing shared memory */ - rv = apr_shm_attach(&shm, fname, pool); + rv = slotmem_attach_shm(&shm, &fname, generation, pool); if (rv != APR_SUCCESS) { return rv; } @@ -598,7 +630,8 @@ static apr_status_t slotmem_attach(ap_slotmem_inst /* For the chained slotmem stuff */ res = apr_pcalloc(pool, sizeof(ap_slotmem_instance_t)); - res->name = apr_pstrdup(pool, fname); + res->name = apr_pstrdup(pool, name); + res->fname = apr_pstrdup(pool, fname); res->fbased = 1; res->shm = shm; res->persist = (void *)ptr;