static apr_status_t cleanup_slotmem(void *param) { ap_slotmem_instance_t **mem = param; if (*mem) { ap_slotmem_instance_t *next = *mem; while (next) { if (AP_SLOTMEM_IS_PERSIST(next)) { store_slotmem(next); } if (next->fbased) { const char *name; apr_shm_remove(next->name, next->gpool); name = slotmem_filename(next->gpool, next->name, 0); if (name) { apr_file_remove(name, next->gpool); } } apr_shm_destroy((apr_shm_t *)next->shm); next = next->next; } } /* apr_pool_destroy(gpool); */ globallistmem = NULL; return APR_SUCCESS; }
static void create_shm(server_rec *s,apr_pool_t *p) { int threaded_mpm; ap_mpm_query(AP_MPMQ_IS_THREADED, &threaded_mpm); //if (threaded_mpm) { tmpnam(lock_name); apr_global_mutex_create(&lock, lock_name, APR_THREAD_MUTEX_DEFAULT, p); //DEBUGLOG("threaded!"); // } size_t size; size = sizeof(client_list_t) + table_size * sizeof(client_t); ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "Create or Joining shmem. name: %s, size: %zd", shmname, size); if(lock) apr_global_mutex_lock(lock); apr_status_t rc = apr_shm_attach(&shm, shmname, p); if (APR_SUCCESS != rc) { DEBUGLOG("dosdetector: Creating shared memory"); apr_shm_remove(shmname, p); rc = apr_shm_create(&shm, size, shmname, p); if (APR_SUCCESS != rc) { ap_log_error(APLOG_MARK, APLOG_ERR, 0,0, "dosdetector: failed to create shared memory %s\n", shmname); //ap_log_error(APLOG_MARK, APLOG_ERR, 0,0, "dosdetector: %s:%d: failed to create shared memory %s\n", __FILE__, __LINE__, shmname); } else { client_list = apr_shm_baseaddr_get(shm); memset(client_list, 0, size); } } else { DEBUGLOG("dosdetector: Joining shared memory"); client_list = apr_shm_baseaddr_get(shm); } apr_shm_remove(shmname, p); // Just to set destroy flag. client_list->head = client_list->base; client_t *c = client_list->base; int i; for (i = 1; i < table_size; i++) { c->next = (c + 1); c++; } c->next = NULL; if (lock) apr_global_mutex_unlock(lock); }
APR_DECLARE(apr_status_t) apr_shm_delete(apr_shm_t *m) { if (m->filename) { return apr_shm_remove(m->filename, m->pool); } else { return APR_ENOTIMPL; } }
int lua_apr_shm_remove(lua_State *L) { apr_status_t status; const char *filename; filename = luaL_checkstring(L, 1); status = apr_shm_remove(filename, to_pool(L)); return push_status(L, status); }
static apr_status_t create_shm(server_rec *s,apr_pool_t *p) { size_t size; apr_status_t rc; size = sizeof(client_list_t) + table_size * sizeof(client_t); if(shmname != NULL) { ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, "creating named shared memory '%s'", shmname); rc = apr_shm_remove(shmname, p); if (APR_SUCCESS == rc) { ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, "removed the existing shared memory segment named '%s'", shmname); } } else { ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, "creating anonymous shared memory"); } rc = apr_shm_create(&shm, size, shmname, p); if (APR_SUCCESS != rc) { return rc; } client_list = apr_shm_baseaddr_get(shm); memset(client_list, 0, size); if(shmname != NULL) { /* prevent other processes from accessing the segment */ apr_shm_remove(shmname, p); } client_list->head = client_list->base; client_t *c = client_list->base; int i; for (i = 1; i < table_size; i++) { c->next = (c + 1); c++; } c->next = NULL; return APR_SUCCESS; }
static void test_named_remove(abts_case *tc, void *data) { apr_status_t rv; apr_shm_t *shm, *shm2; apr_shm_remove(SHARED_FILENAME, p); rv = apr_shm_create(&shm, SHARED_SIZE, SHARED_FILENAME, p); APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv); if (rv != APR_SUCCESS) { return; } ABTS_PTR_NOTNULL(tc, shm); rv = apr_shm_remove(SHARED_FILENAME, p); /* On platforms which acknowledge the removal of the shared resource, * ensure another of the same name may be created after removal; */ if (rv == APR_SUCCESS) { rv = apr_shm_create(&shm2, SHARED_SIZE, SHARED_FILENAME, p); APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv); if (rv != APR_SUCCESS) { return; } ABTS_PTR_NOTNULL(tc, shm2); rv = apr_shm_destroy(shm2); APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv); } rv = apr_shm_destroy(shm); APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv); /* Now ensure no named resource remains which we may attach to */ rv = apr_shm_attach(&shm, SHARED_FILENAME, p); ABTS_TRUE(tc, rv != 0); }
apr_status_t upload_progress_cache_init(apr_pool_t *pool, ServerConfig *config) { #if APR_HAS_SHARED_MEMORY apr_status_t result; apr_size_t size; upload_progress_cache_t *cache; apr_rmm_off_t block; if (config->cache_file) { /* Remove any existing shm segment with this name. */ apr_shm_remove(config->cache_file, config->pool); } size = APR_ALIGN_DEFAULT(config->cache_bytes); result = apr_shm_create(&config->cache_shm, size, config->cache_file, config->pool); if (result != APR_SUCCESS) { return result; } /* Determine the usable size of the shm segment. */ size = apr_shm_size_get(config->cache_shm); /* This will create a rmm "handler" to get into the shared memory area */ result = apr_rmm_init(&config->cache_rmm, NULL, apr_shm_baseaddr_get(config->cache_shm), size, config->pool); if (result != APR_SUCCESS) { return result; } apr_pool_cleanup_register(config->pool, config , upload_progress_cache_module_kill, apr_pool_cleanup_null); /* init cache object */ CACHE_LOCK(); block = apr_rmm_calloc(config->cache_rmm, sizeof(upload_progress_cache_t)); cache = block ? (upload_progress_cache_t *)apr_rmm_addr_get(config->cache_rmm, block) : NULL; if(cache == NULL) { CACHE_UNLOCK(); return 0; } cache->head = NULL; config->cache_offset = block; config->cache = cache; CACHE_UNLOCK(); #endif return APR_SUCCESS; }
apr_status_t util_ldap_cache_init(apr_pool_t *pool, util_ldap_state_t *st) { #if APR_HAS_SHARED_MEMORY apr_status_t result; apr_size_t size; if (st->cache_bytes > 0) { if (st->cache_file) { /* Remove any existing shm segment with this name. */ apr_shm_remove(st->cache_file, st->pool); } size = APR_ALIGN_DEFAULT(st->cache_bytes); result = apr_shm_create(&st->cache_shm, size, st->cache_file, st->pool); if (result != APR_SUCCESS) { return result; } /* Determine the usable size of the shm segment. */ size = apr_shm_size_get(st->cache_shm); /* This will create a rmm "handler" to get into the shared memory area */ result = apr_rmm_init(&st->cache_rmm, NULL, apr_shm_baseaddr_get(st->cache_shm), size, st->pool); if (result != APR_SUCCESS) { return result; } } #endif apr_pool_cleanup_register(st->pool, st , util_ldap_cache_module_kill, apr_pool_cleanup_null); st->util_ldap_cache = util_ald_create_cache(st, st->search_cache_size, st->search_cache_ttl, util_ldap_url_node_hash, util_ldap_url_node_compare, util_ldap_url_node_copy, util_ldap_url_node_free, util_ldap_url_node_display); return APR_SUCCESS; }
/** * Create a name-based scoreboard in the given pool using the * given filename. */ static apr_status_t create_namebased_scoreboard(apr_pool_t *pool, const char *fname) { #if APR_HAS_SHARED_MEMORY apr_status_t rv; /* The shared memory file must not exist before we create the * segment. */ apr_shm_remove(fname, pool); /* ignore errors */ rv = apr_shm_create(&ap_scoreboard_shm, scoreboard_size, fname, pool); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, "unable to create or access scoreboard \"%s\" " "(name-based shared memory failure)", fname); return rv; } #endif /* APR_HAS_SHARED_MEMORY */ return APR_SUCCESS; }
static void test_named(abts_case *tc, void *data) { apr_status_t rv; apr_shm_t *shm = NULL; apr_size_t retsize; apr_proc_t pidproducer, pidconsumer; apr_procattr_t *attr1 = NULL, *attr2 = NULL; int sent, received; apr_exit_why_e why; const char *args[4]; apr_shm_remove(SHARED_FILENAME, p); rv = apr_shm_create(&shm, SHARED_SIZE, SHARED_FILENAME, p); APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv); if (rv != APR_SUCCESS) { return; } ABTS_PTR_NOTNULL(tc, shm); retsize = apr_shm_size_get(shm); ABTS_SIZE_EQUAL(tc, SHARED_SIZE, retsize); boxes = apr_shm_baseaddr_get(shm); ABTS_PTR_NOTNULL(tc, boxes); rv = apr_procattr_create(&attr1, p); ABTS_PTR_NOTNULL(tc, attr1); APR_ASSERT_SUCCESS(tc, "Couldn't create attr1", rv); rv = apr_procattr_cmdtype_set(attr1, APR_PROGRAM_ENV); APR_ASSERT_SUCCESS(tc, "Couldn't set copy environment", rv); args[0] = apr_pstrdup(p, "testshmproducer" EXTENSION); args[1] = NULL; rv = apr_proc_create(&pidproducer, TESTBINPATH "testshmproducer" EXTENSION, args, NULL, attr1, p); APR_ASSERT_SUCCESS(tc, "Couldn't launch producer", rv); rv = apr_procattr_create(&attr2, p); ABTS_PTR_NOTNULL(tc, attr2); APR_ASSERT_SUCCESS(tc, "Couldn't create attr2", rv); rv = apr_procattr_cmdtype_set(attr2, APR_PROGRAM_ENV); APR_ASSERT_SUCCESS(tc, "Couldn't set copy environment", rv); args[0] = apr_pstrdup(p, "testshmconsumer" EXTENSION); rv = apr_proc_create(&pidconsumer, TESTBINPATH "testshmconsumer" EXTENSION, args, NULL, attr2, p); APR_ASSERT_SUCCESS(tc, "Couldn't launch consumer", rv); rv = apr_proc_wait(&pidconsumer, &received, &why, APR_WAIT); ABTS_INT_EQUAL(tc, APR_CHILD_DONE, rv); ABTS_INT_EQUAL(tc, APR_PROC_EXIT, why); rv = apr_proc_wait(&pidproducer, &sent, &why, APR_WAIT); ABTS_INT_EQUAL(tc, APR_CHILD_DONE, rv); ABTS_INT_EQUAL(tc, APR_PROC_EXIT, why); /* Cleanup before testing that producer and consumer worked correctly. * This way, if they didn't succeed, we can just run this test again * without having to cleanup manually. */ APR_ASSERT_SUCCESS(tc, "Error destroying shared memory", apr_shm_destroy(shm)); ABTS_INT_EQUAL(tc, sent, received); }
void ssl_scache_shmcb_init(server_rec *s, apr_pool_t *p) { SSLModConfigRec *mc = myModConfig(s); void *shm_segment; apr_size_t shm_segsize; apr_status_t rv; SHMCBHeader *header; unsigned int num_subcache, num_idx, loop; /* Create shared memory segment */ if (mc->szSessionCacheDataFile == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "SSLSessionCache required"); ssl_die(); } /* Use anonymous shm by default, fall back on name-based. */ rv = apr_shm_create(&(mc->pSessionCacheDataMM), mc->nSessionCacheDataSize, NULL, mc->pPool); if (APR_STATUS_IS_ENOTIMPL(rv)) { /* For a name-based segment, remove it first in case of a * previous unclean shutdown. */ apr_shm_remove(mc->szSessionCacheDataFile, mc->pPool); rv = apr_shm_create(&(mc->pSessionCacheDataMM), mc->nSessionCacheDataSize, mc->szSessionCacheDataFile, mc->pPool); } if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "could not allocate shared memory for shmcb " "session cache"); ssl_die(); } shm_segment = apr_shm_baseaddr_get(mc->pSessionCacheDataMM); shm_segsize = apr_shm_size_get(mc->pSessionCacheDataMM); if (shm_segsize < (5 * sizeof(SHMCBHeader))) { /* the segment is ridiculously small, bail out */ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "shared memory segment too small"); ssl_die(); } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "shmcb_init allocated %" APR_SIZE_T_FMT " bytes of shared memory", shm_segsize); /* Discount the header */ shm_segsize -= sizeof(SHMCBHeader); /* Select the number of subcaches to create and how many indexes each * should contain based on the size of the memory (the header has already * been subtracted). Typical non-client-auth sslv3/tlsv1 sessions are * around 150 bytes, so erring to division by 120 helps ensure we would * exhaust data storage before index storage (except sslv2, where it's * *slightly* the other way). From there, we select the number of subcaches * to be a power of two, such that the number of indexes per subcache at * least twice the number of subcaches. */ num_idx = (shm_segsize) / 120; num_subcache = 256; while ((num_idx / num_subcache) < (2 * num_subcache)) num_subcache /= 2; num_idx /= num_subcache; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "for %" APR_SIZE_T_FMT " bytes (%" APR_SIZE_T_FMT " including header), recommending %u subcaches, " "%u indexes each", shm_segsize, shm_segsize + sizeof(SHMCBHeader), num_subcache, num_idx); if (num_idx < 5) { /* we're still too small, bail out */ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "shared memory segment too small"); ssl_die(); } /* OK, we're sorted */ header = shm_segment; header->stat_stores = 0; header->stat_expiries = 0; header->stat_scrolled = 0; header->stat_retrieves_hit = 0; header->stat_retrieves_miss = 0; header->stat_removes_hit = 0; header->stat_removes_miss = 0; header->subcache_num = num_subcache; /* Convert the subcache size (in bytes) to a value that is suitable for * structure alignment on the host platform, by rounding down if necessary. * This assumes that sizeof(unsigned long) provides an appropriate * alignment unit. */ header->subcache_size = ((size_t)(shm_segsize / num_subcache) & ~(size_t)(sizeof(unsigned long) - 1)); header->subcache_data_offset = sizeof(SHMCBSubcache) + num_idx * sizeof(SHMCBIndex); header->subcache_data_size = header->subcache_size - header->subcache_data_offset; header->index_num = num_idx; /* Output trace info */ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "shmcb_init_memory choices follow"); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "subcache_num = %u", header->subcache_num); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "subcache_size = %u", header->subcache_size); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "subcache_data_offset = %u", header->subcache_data_offset); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "subcache_data_size = %u", header->subcache_data_size); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "index_num = %u", header->index_num); /* The header is done, make the caches empty */ for (loop = 0; loop < header->subcache_num; loop++) { SHMCBSubcache *subcache = SHMCB_SUBCACHE(header, loop); subcache->idx_pos = subcache->idx_used = 0; subcache->data_pos = subcache->data_used = 0; } ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "Shared memory session cache initialised"); /* Success ... */ mc->tSessionCacheDataTable = shm_segment; }