mod_sharedmem.c revision 908fa24e93608edc48387d1348de5fd8ff9d60c4
083eacf86f9327835b824f9e6be987d56cd96e82slive/* Licensed to the Apache Software Foundation (ASF) under one or more
530eba85dbd41b8a0fa5255d3648d1440199a661slive * contributor license agreements. See the NOTICE file distributed with
083eacf86f9327835b824f9e6be987d56cd96e82slive * this work for additional information regarding copyright ownership.
083eacf86f9327835b824f9e6be987d56cd96e82slive * The ASF licenses this file to You under the Apache License, Version 2.0
083eacf86f9327835b824f9e6be987d56cd96e82slive * (the "License"); you may not use this file except in compliance with
083eacf86f9327835b824f9e6be987d56cd96e82slive * the License. You may obtain a copy of the License at
083eacf86f9327835b824f9e6be987d56cd96e82slive * Unless required by applicable law or agreed to in writing, software
083eacf86f9327835b824f9e6be987d56cd96e82slive * distributed under the License is distributed on an "AS IS" BASIS,
083eacf86f9327835b824f9e6be987d56cd96e82slive * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
083eacf86f9327835b824f9e6be987d56cd96e82slive * See the License for the specific language governing permissions and
083eacf86f9327835b824f9e6be987d56cd96e82slive * limitations under the License.
083eacf86f9327835b824f9e6be987d56cd96e82slive/* Memory handler for a shared memory divided in slot.
083eacf86f9327835b824f9e6be987d56cd96e82slive * This one uses shared memory.
083eacf86f9327835b824f9e6be987d56cd96e82slive#if !defined(SHM_R)
083eacf86f9327835b824f9e6be987d56cd96e82slive#if !defined(SHM_W)
083eacf86f9327835b824f9e6be987d56cd96e82slive struct ap_slotmem_t *next; /* location of next allocated segment */
083eacf86f9327835b824f9e6be987d56cd96e82slive/* The description of the slots to reuse the slotmem */
083eacf86f9327835b824f9e6be987d56cd96e82slive unsigned int item_num;
083eacf86f9327835b824f9e6be987d56cd96e82slive * Memory layout:
083eacf86f9327835b824f9e6be987d56cd96e82slive * sharedslotdesc | slots | isuse array
083eacf86f9327835b824f9e6be987d56cd96e82slive/* global pool and list of slotmem we are handling */
083eacf86f9327835b824f9e6be987d56cd96e82slive#define SLOTMEM_LOCK(s) do { \
083eacf86f9327835b824f9e6be987d56cd96e82slive#define SLOTMEM_UNLOCK(s) do { \
083eacf86f9327835b824f9e6be987d56cd96e82slivestatic apr_status_t unixd_set_shm_perms(const char *fname)
530eba85dbd41b8a0fa5255d3648d1440199a661slive if ((shmid = shmget(shmkey, 0, SHM_R | SHM_W)) == -1) {
083eacf86f9327835b824f9e6be987d56cd96e82slive * Persiste the slotmem in a file
083eacf86f9327835b824f9e6be987d56cd96e82slive * slotmem name and file name.
083eacf86f9327835b824f9e6be987d56cd96e82slive * abs_name : $abs_name.slotmem
083eacf86f9327835b824f9e6be987d56cd96e82slivestatic const char *store_filename(apr_pool_t *pool, const char *slotmemname)
083eacf86f9327835b824f9e6be987d56cd96e82slive const char *storename;
083eacf86f9327835b824f9e6be987d56cd96e82slive const char *fname;
083eacf86f9327835b824f9e6be987d56cd96e82slive fname = ap_server_root_relative(pool, "logs/anonymous");
083eacf86f9327835b824f9e6be987d56cd96e82slive const char *tmpname;
083eacf86f9327835b824f9e6be987d56cd96e82slive tmpname = apr_pstrcat(pool, "logs/", &slotmemname[1], NULL);
083eacf86f9327835b824f9e6be987d56cd96e82slive storename = apr_pstrcat(pool, fname, ".slotmem", NULL);
083eacf86f9327835b824f9e6be987d56cd96e82slive const char *storename;
083eacf86f9327835b824f9e6be987d56cd96e82slive storename = store_filename(slotmem->gpool, slotmem->name);
083eacf86f9327835b824f9e6be987d56cd96e82slive rv = apr_file_open(&fp, storename, APR_CREATE | APR_READ | APR_WRITE, APR_OS_DEFAULT, slotmem->gpool);
083eacf86f9327835b824f9e6be987d56cd96e82slive rv = apr_file_open(&fp, storename, APR_CREATE | APR_READ | APR_WRITE, APR_OS_DEFAULT, slotmem->gpool);
083eacf86f9327835b824f9e6be987d56cd96e82slive nbytes = (slotmem->size * slotmem->num) + (slotmem->num * sizeof(char));
083eacf86f9327835b824f9e6be987d56cd96e82slivestatic void restore_slotmem(void *ptr, const char *name, apr_size_t size, apr_pool_t *pool)
083eacf86f9327835b824f9e6be987d56cd96e82slive const char *storename;
083eacf86f9327835b824f9e6be987d56cd96e82slive rv = apr_file_open(&fp, storename, APR_READ | APR_WRITE, APR_OS_DEFAULT, pool);
083eacf86f9327835b824f9e6be987d56cd96e82slive if (apr_file_info_get(&fi, APR_FINFO_SIZE, fp) == APR_SUCCESS) {
083eacf86f9327835b824f9e6be987d56cd96e82slivestatic apr_status_t slotmem_do(ap_slotmem_t *mem, ap_slotmem_callback_fn_t *func, void *data, apr_pool_t *pool)
083eacf86f9327835b824f9e6be987d56cd96e82slive unsigned int i;
083eacf86f9327835b824f9e6be987d56cd96e82slivestatic apr_status_t slotmem_create(ap_slotmem_t **new, const char *name, apr_size_t item_size, unsigned int item_num, apslotmem_type type, apr_pool_t *pool)
083eacf86f9327835b824f9e6be987d56cd96e82slive/* void *slotmem = NULL; */
083eacf86f9327835b824f9e6be987d56cd96e82slive const char *fname;
083eacf86f9327835b824f9e6be987d56cd96e82slive apr_size_t size = sizeof(struct sharedslotdesc) + (item_num * sizeof(char)) + basesize;
083eacf86f9327835b824f9e6be987d56cd96e82slive /* first try to attach to existing slotmem */
083eacf86f9327835b824f9e6be987d56cd96e82slive /* we already have it */
083eacf86f9327835b824f9e6be987d56cd96e82slive /* first try to attach to existing shared memory */
083eacf86f9327835b824f9e6be987d56cd96e82slive /* check size */
083eacf86f9327835b824f9e6be987d56cd96e82slive if (desc.item_size != item_size || desc.item_num != item_num) {
083eacf86f9327835b824f9e6be987d56cd96e82slive apr_size_t dsize = size - sizeof(struct sharedslotdesc);
083eacf86f9327835b824f9e6be987d56cd96e82slive /* Set permissions to shared memory
083eacf86f9327835b824f9e6be987d56cd96e82slive * so it can be attached by child process
083eacf86f9327835b824f9e6be987d56cd96e82slive * having different user credentials
083eacf86f9327835b824f9e6be987d56cd96e82slive /* For the chained slotmem stuff */
083eacf86f9327835b824f9e6be987d56cd96e82slive res = (ap_slotmem_t *) apr_pcalloc(gpool, sizeof(ap_slotmem_t));
083eacf86f9327835b824f9e6be987d56cd96e82slivestatic apr_status_t slotmem_attach(ap_slotmem_t **new, const char *name, apr_size_t *item_size, unsigned int *item_num, apr_pool_t *pool)
083eacf86f9327835b824f9e6be987d56cd96e82slive/* void *slotmem = NULL; */
083eacf86f9327835b824f9e6be987d56cd96e82slive const char *fname;
083eacf86f9327835b824f9e6be987d56cd96e82slive /* first try to attach to existing slotmem */
083eacf86f9327835b824f9e6be987d56cd96e82slive /* we already have it */
083eacf86f9327835b824f9e6be987d56cd96e82slive /* first try to attach to existing shared memory */
083eacf86f9327835b824f9e6be987d56cd96e82slive /* Read the description of the slotmem */
083eacf86f9327835b824f9e6be987d56cd96e82slive /* For the chained slotmem stuff */
083eacf86f9327835b824f9e6be987d56cd96e82slive res = (ap_slotmem_t *) apr_pcalloc(gpool, sizeof(ap_slotmem_t));
083eacf86f9327835b824f9e6be987d56cd96e82slivestatic apr_status_t slotmem_mem(ap_slotmem_t *slot, unsigned int id, void **mem)
083eacf86f9327835b824f9e6be987d56cd96e82slivestatic apr_status_t slotmem_get(ap_slotmem_t *slot, unsigned int id, unsigned char *dest, apr_size_t dest_len)
083eacf86f9327835b824f9e6be987d56cd96e82slivestatic apr_status_t slotmem_put(ap_slotmem_t *slot, unsigned int id, unsigned char *src, apr_size_t src_len)
083eacf86f9327835b824f9e6be987d56cd96e82slive /* We know the id fit it */
083eacf86f9327835b824f9e6be987d56cd96e82slivestatic unsigned int slotmem_num_slots(ap_slotmem_t *slot)
083eacf86f9327835b824f9e6be987d56cd96e82slivestatic apr_size_t slotmem_slot_size(ap_slotmem_t *slot)
083eacf86f9327835b824f9e6be987d56cd96e82slive "sharedmem",
083eacf86f9327835b824f9e6be987d56cd96e82slive/* make the storage usuable from outside */
530eba85dbd41b8a0fa5255d3648d1440199a661slivestatic const ap_slotmem_storage_method *sharedmem_getstorage(void)
083eacf86f9327835b824f9e6be987d56cd96e82slive/* initialise the global pool */
083eacf86f9327835b824f9e6be987d56cd96e82slive/* Add the pool_clean routine */
083eacf86f9327835b824f9e6be987d56cd96e82slivestatic void sharedmem_initialize_cleanup(apr_pool_t *p)
083eacf86f9327835b824f9e6be987d56cd96e82slive apr_pool_cleanup_register(p, &globallistmem, cleanup_slotmem, apr_pool_cleanup_null);
083eacf86f9327835b824f9e6be987d56cd96e82slive * Create the shared mem mutex and
083eacf86f9327835b824f9e6be987d56cd96e82slive * make sure the shared memory is cleaned
530eba85dbd41b8a0fa5255d3648d1440199a661slivestatic int post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
083eacf86f9327835b824f9e6be987d56cd96e82slive const char *temp_dir;
083eacf86f9327835b824f9e6be987d56cd96e82slive apr_pool_userdata_get(&data, userdata_key, s->process->pool);
083eacf86f9327835b824f9e6be987d56cd96e82slive "sharedmem: search for temporary directory failed");
083eacf86f9327835b824f9e6be987d56cd96e82slive apr_filepath_merge(&template, temp_dir, "sharedmem.lck.XXXXXX",
083eacf86f9327835b824f9e6be987d56cd96e82slive "sharedmem: creation of mutex file in directory %s failed",
083eacf86f9327835b824f9e6be987d56cd96e82slive "sharedmem: unable to get mutex fname");
083eacf86f9327835b824f9e6be987d56cd96e82slive "sharedmem: could not close mutex file");
083eacf86f9327835b824f9e6be987d56cd96e82slive "sharedmem: creation of mutex failed");
083eacf86f9327835b824f9e6be987d56cd96e82slive "sharedmem: failed to set mutex permissions");
083eacf86f9327835b824f9e6be987d56cd96e82slive "Fatal error: unable to create global pool for shared slotmem");
083eacf86f9327835b824f9e6be987d56cd96e82slive "Failed to initialise global mutex %s in child process %"
083eacf86f9327835b824f9e6be987d56cd96e82slive const ap_slotmem_storage_method *storage = sharedmem_getstorage();
083eacf86f9327835b824f9e6be987d56cd96e82slive ap_register_provider(p, AP_SLOTMEM_STORAGE, "shared", "0", storage);
530eba85dbd41b8a0fa5255d3648d1440199a661slive ap_hook_post_config(post_config, NULL, NULL, APR_HOOK_LAST);
083eacf86f9327835b824f9e6be987d56cd96e82slive ap_hook_pre_config(pre_config, NULL, NULL, APR_HOOK_MIDDLE);