/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.
*/
/* * ToDo: * This function should be renamed to cleanup_shared * and it should handle cleaning up a scoreboard shared * between processes using any form of IPC (file, shared memory * segment, etc.). Leave it as is now because it is being used * by various MPMs.
*/ static apr_status_t ap_cleanup_shared_mem(void *d)
{ #if APR_HAS_SHARED_MEMORY
free(ap_scoreboard_image);
ap_scoreboard_image = NULL;
apr_shm_destroy(ap_scoreboard_shm); #endif 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, constchar *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 */
/* ToDo: This function should be made to handle setting up * a scoreboard shared between processes using any IPC technique, * not just a shared memory segment
*/ static apr_status_t open_scoreboard(apr_pool_t *pconf)
{ #if APR_HAS_SHARED_MEMORY
apr_status_t rv; char *fname = NULL;
apr_pool_t *global_pool;
/* We don't want to have to recreate the scoreboard after * restarts, so we'll create a global pool and never clean it.
*/
rv = apr_pool_create(&global_pool, NULL); if (rv != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, APLOGNO(00002) "Fatal error: unable to create global pool " "for use by the scoreboard"); return rv;
}
/* The config says to create a name-based shmem */ if (ap_scoreboard_fname) { /* make sure it's an absolute pathname */
fname = ap_server_root_relative(pconf, ap_scoreboard_fname); if (!fname) {
ap_log_error(APLOG_MARK, APLOG_CRIT, APR_EBADPATH, ap_server_conf, APLOGNO(00003) "Fatal error: Invalid Scoreboard path %s",
ap_scoreboard_fname); return APR_EBADPATH;
} return create_namebased_scoreboard(global_pool, fname);
} else { /* config didn't specify, we get to choose shmem type */
rv = apr_shm_create(&ap_scoreboard_shm, scoreboard_size, NULL,
global_pool); /* anonymous shared memory */ if ((rv != APR_SUCCESS) && (rv != APR_ENOTIMPL)) {
ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, APLOGNO(00004) "Unable to create or access scoreboard " "(anonymous shared memory failure)"); return rv;
} /* Make up a filename and do name-based shmem */ elseif (rv == APR_ENOTIMPL) { /* Make sure it's an absolute pathname */
ap_scoreboard_fname = DEFAULT_SCOREBOARD;
fname = ap_server_root_relative(pconf, ap_scoreboard_fname);
/* If detach is non-zero, this is a separate child process, * if zero, it is a forked child.
*/
AP_DECLARE(apr_status_t) ap_reopen_scoreboard(apr_pool_t *p, apr_shm_t **shm, int detached)
{ #if APR_HAS_SHARED_MEMORY if (!detached) { return APR_SUCCESS;
} if (apr_shm_size_get(ap_scoreboard_shm) < scoreboard_size) {
ap_log_error(APLOG_MARK, APLOG_CRIT, 0, ap_server_conf, APLOGNO(00005) "Fatal error: shared scoreboard too small for child!");
apr_shm_detach(ap_scoreboard_shm);
ap_scoreboard_shm = NULL; return APR_EINVAL;
} /* everything will be cleared shortly */ if (*shm) {
*shm = ap_scoreboard_shm;
} #endif return APR_SUCCESS;
}
/* Create or reinit an existing scoreboard. The MPM can control whether * the scoreboard is shared across multiple processes or not
*/ int ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e sb_type)
{ int i; #if APR_HAS_SHARED_MEMORY
apr_status_t rv; #endif
if (ap_scoreboard_image) {
ap_scoreboard_image->global->restart_time = apr_time_now();
memset(ap_scoreboard_image->parent, 0,
SIZE_OF_process_score * server_limit); for (i = 0; i < server_limit; i++) {
memset(ap_scoreboard_image->servers[i], 0,
SIZE_OF_worker_score * thread_limit);
}
ap_init_scoreboard(NULL); return OK;
}
/* Routines called to deal with the scoreboard image * --- note that we do *not* need write locks, since update_child_status * only updates a *single* record in place, and only one process writes to * a given scoreboard slot at a time (either the child process owning that * slot, or the parent, noting that the child has died). * * As a final note --- setting the score entry to getpid() is always safe, * since when the parent is writing an entry, it's only noting SERVER_DEAD * anyway.
*/
if (r->the_request == NULL) {
apr_cpystrn(rbuf, "NULL", rbuflen); return; /* short circuit below */
}
if (r->parsed_uri.password == NULL) {
p = r->the_request;
} else { /* Don't reveal the password in the server-status view */
p = apr_pstrcat(r->pool, r->method, " ",
apr_uri_unparse(r->pool, &r->parsed_uri,
APR_URI_UNP_OMITPASSWORD),
r->assbackwards ? NULL : " ", r->protocol, NULL);
}
/* now figure out if we copy over the 1st rbuflen chars or the last */ if (!ap_mod_status_reqtail) {
apr_cpystrn(rbuf, p, rbuflen);
} else {
apr_size_t slen = strlen(p); if (slen < rbuflen) { /* it all fits anyway */
apr_cpystrn(rbuf, p, rbuflen);
} else {
apr_cpystrn(rbuf, p+(slen-rbuflen+1), rbuflen);
}
}
}
staticint update_child_status_internal(int child_num, int thread_num, int status,
conn_rec *c,
server_rec *s,
request_rec *r, constchar *descr)
{ int old_status;
worker_score *ws; int mpm_generation;
AP_DECLARE(void) ap_copy_scoreboard_worker(worker_score *dest, int child_num, int thread_num)
{
worker_score *ws = ap_get_scoreboard_worker_from_indexes(child_num, thread_num);
memcpy(dest, ws, sizeof *ws);
/* For extra safety, NUL-terminate the strings returned, though it
* should be true those last bytes are always zero anyway. */
dest->client[sizeof(dest->client) - 1] = '\0';
dest->client64[sizeof(dest->client64) - 1] = '\0';
dest->request[sizeof(dest->request) - 1] = '\0';
dest->vhost[sizeof(dest->vhost) - 1] = '\0';
dest->protocol[sizeof(dest->protocol) - 1] = '\0';
}
AP_DECLARE(process_score *) ap_get_scoreboard_process(int x)
{ if ((x < 0) || (x >= server_limit)) { return(NULL); /* Out of range */
} return &ap_scoreboard_image->parent[x];
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.