mod_slotmem_shm.c revision 714a36287cb6cc92748d7e87bbe549d660acae1c
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina/* Licensed to the Apache Software Foundation (ASF) under one or more
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina * contributor license agreements. See the NOTICE file distributed with
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina * this work for additional information regarding copyright ownership.
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina * The ASF licenses this file to You under the Apache License, Version 2.0
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina * (the "License"); you may not use this file except in compliance with
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina * the License. You may obtain a copy of the License at
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina * Unless required by applicable law or agreed to in writing, software
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina * distributed under the License is distributed on an "AS IS" BASIS,
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina * See the License for the specific language governing permissions and
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina * limitations under the License.
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina/* Memory handler for a shared memory divided in slot.
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina * This one uses shared memory.
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina * Shared memory is cleaned-up for each restart, graceful or
ab0eda3622b828df2bfb7850c96d1395f614eb13Pavel Březina#define AP_SLOTMEM_IS_PREGRAB(t) (t->desc.type & AP_SLOTMEM_TYPE_PREGRAB)
ab0eda3622b828df2bfb7850c96d1395f614eb13Pavel Březina#define AP_SLOTMEM_IS_PERSIST(t) (t->desc.type & AP_SLOTMEM_TYPE_PERSIST)
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina/* The description of the slots to reuse the slotmem */
ab0eda3622b828df2bfb7850c96d1395f614eb13Pavel Březinatypedef struct {
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina apr_size_t size; /* size of each memory slot */
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina ap_slotmem_type_t type; /* type-specific flags */
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina#define AP_SLOTMEM_OFFSET (APR_ALIGN_DEFAULT(sizeof(sharedslotdesc_t)))
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov#define AP_UNSIGNEDINT_OFFSET (APR_ALIGN_DEFAULT(sizeof(unsigned int)))
b0d3164ca2bd842e176268c26935c5ce54f7f76ePavel Březina void *shm; /* ptr to memory segment (apr_shm_t *) */
b0d3164ca2bd842e176268c26935c5ce54f7f76ePavel Březina apr_pool_t *gpool; /* per segment global pool */
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina unsigned int *num_free; /* slot free count for this instance */
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina struct ap_slotmem_instance_t *next; /* location of next allocated segment */
b0d3164ca2bd842e176268c26935c5ce54f7f76ePavel Březina * Memory layout:
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina * sharedslotdesc_t | num_free | slots | isuse array |
ab0eda3622b828df2bfb7850c96d1395f614eb13Pavel Březina * . persist (also num_free)
ab0eda3622b828df2bfb7850c96d1395f614eb13Pavel Březina/* global pool and list of slotmem we are handling */
ab0eda3622b828df2bfb7850c96d1395f614eb13Pavel Březinastatic struct ap_slotmem_instance_t *globallistmem = NULL;
ab0eda3622b828df2bfb7850c96d1395f614eb13Pavel Březinastatic apr_status_t unixd_set_shm_perms(const char *fname)
ab0eda3622b828df2bfb7850c96d1395f614eb13Pavel Březina#if APR_USE_SHMEM_SHMGET || APR_USE_SHMEM_SHMGET_ANON
ab0eda3622b828df2bfb7850c96d1395f614eb13Pavel Březina if ((shmid = shmget(shmkey, 0, SHM_R | SHM_W)) == -1) {
ab0eda3622b828df2bfb7850c96d1395f614eb13Pavel Březina shmbuf.shm_perm.uid = ap_unixd_config.user_id;
ab0eda3622b828df2bfb7850c96d1395f614eb13Pavel Březina shmbuf.shm_perm.gid = ap_unixd_config.group_id;
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina * Persist the slotmem in a file
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina * slotmem name and file name.
ab0eda3622b828df2bfb7850c96d1395f614eb13Pavel Březina * none : no persistent data
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina * anonymous : $server_root/logs/anonymous.slotmem
ab0eda3622b828df2bfb7850c96d1395f614eb13Pavel Březina * :rel_name : $server_root/logs/rel_name.slotmem
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina * abs_name : $abs_name.slotmem
ab0eda3622b828df2bfb7850c96d1395f614eb13Pavel Březinastatic const char *store_filename(apr_pool_t *pool, const char *slotmemname)
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina else if (strcasecmp(slotmemname, "anonymous") == 0)
ab0eda3622b828df2bfb7850c96d1395f614eb13Pavel Březina fname = ap_server_root_relative(pool, "logs/anonymous");
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina tmpname = apr_pstrcat(pool, "logs/", &slotmemname[1], NULL);
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina fname = ap_server_root_relative(pool, tmpname);
ab0eda3622b828df2bfb7850c96d1395f614eb13Pavel Březina storename = apr_pstrcat(pool, fname, ".slotmem", NULL);
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březinastatic void store_slotmem(ap_slotmem_instance_t *slotmem)
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina storename = store_filename(slotmem->gpool, slotmem->name);
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina rv = apr_file_open(&fp, storename, APR_CREATE | APR_READ | APR_WRITE,
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina rv = apr_file_open(&fp, storename, APR_CREATE | APR_READ | APR_WRITE,
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina nbytes = (slotmem->desc.size * slotmem->desc.num) +
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina (slotmem->desc.num * sizeof(char)) + AP_UNSIGNEDINT_OFFSET;
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina apr_file_write(fp, slotmem->persist, &nbytes);
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina/* should be apr_status_t really */
ab0eda3622b828df2bfb7850c96d1395f614eb13Pavel Březinastatic void restore_slotmem(void *ptr, const char *name, apr_size_t size,
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina rv = apr_file_open(&fp, storename, APR_READ | APR_WRITE, APR_OS_DEFAULT,
7b5e7e539ae9312ab55d75aa94feaad549b2a708Pavel Březina if (apr_file_info_get(&fi, APR_FINFO_SIZE, fp) == APR_SUCCESS) {
17531a398cc9084036cb08d69fe876a8f12707bbPavel Březinastatic apr_status_t cleanup_slotmem(void *param)
17531a398cc9084036cb08d69fe876a8f12707bbPavel Březina /* apr_pool_destroy(gpool); */
17531a398cc9084036cb08d69fe876a8f12707bbPavel Březinastatic apr_status_t slotmem_doall(ap_slotmem_instance_t *mem,
17531a398cc9084036cb08d69fe876a8f12707bbPavel Březina unsigned int i;
if (!mem) {
return APR_ENOSHMAVAIL;
return retval;
unsigned int item_num,
int fbased;
char *ptr;
const char *fname;
return APR_ENOSHMAVAIL;
if (name) {
if (next) {
return APR_SUCCESS;
if (fbased) {
return APR_EINVAL;
return APR_EINVAL;
if (fbased) {
return rv;
if (fbased) {
sizeof(ap_slotmem_instance_t));
return APR_SUCCESS;
char *ptr;
const char *fname;
return APR_ENOSHMAVAIL;
if (name) {
return APR_ENOSHMAVAIL;
if (next) {
return APR_SUCCESS;
return rv;
sizeof(ap_slotmem_instance_t));
return APR_SUCCESS;
char *ptr;
if (!slot) {
return APR_ENOSHMAVAIL;
return APR_ENOSHMAVAIL;
if (!ptr) {
return APR_ENOSHMAVAIL;
return APR_SUCCESS;
void *ptr;
char *inuse;
if (!slot) {
return APR_ENOSHMAVAIL;
return APR_NOTFOUND;
return ret;
return APR_SUCCESS;
void *ptr;
char *inuse;
if (!slot) {
return APR_ENOSHMAVAIL;
return APR_NOTFOUND;
return ret;
return APR_SUCCESS;
unsigned int i, counter=0;
if (!*inuse)
counter++;
return counter;
char *inuse;
if (!slot) {
return APR_ENOSHMAVAIL;
if (!*inuse) {
return APR_EINVAL;
*id = i;
return APR_SUCCESS;
unsigned int id)
char *inuse;
if (!slot) {
return APR_ENOSHMAVAIL;
return APR_NOTFOUND;
return APR_SUCCESS;
return (&storage);
gpool = p;
server_rec *s)
return OK;
return OK;