diff --git a/modules/generators/mod_status.c b/modules/generators/mod_status.c index 9b1c515b268..4f3b1323e4b 100644 --- a/modules/generators/mod_status.c +++ b/modules/generators/mod_status.c @@ -71,6 +71,7 @@ #define APR_WANT_STRFUNC #include "apr_want.h" #include "apr_strings.h" +#include "apr_atomic.h" #define STATUS_MAXLINE 64 @@ -200,9 +201,13 @@ static int status_handler(request_rec *r) int no_table_report; global_score *global_record; worker_score *ws_record; - process_score *ps_record; + process_score *ps_record = NULL; char *stat_buffer; - pid_t *pid_buffer, worker_pid; + pid_t worker_pid; + struct { + pid_t pid; + ap_generation_t gen; + } *proc_buffer = NULL; int *thread_idle_buffer = NULL; int *thread_graceful_buffer = NULL; int *thread_busy_buffer = NULL; @@ -249,7 +254,7 @@ static int status_handler(request_rec *r) return HTTP_INTERNAL_SERVER_ERROR; } - pid_buffer = apr_palloc(r->pool, server_limit * sizeof(pid_t)); + proc_buffer = apr_palloc(r->pool, server_limit * sizeof(*proc_buffer)); stat_buffer = apr_palloc(r->pool, server_limit * thread_limit * sizeof(char)); if (is_async) { thread_idle_buffer = apr_palloc(r->pool, server_limit * sizeof(int)); @@ -314,12 +319,15 @@ static int status_handler(request_rec *r) ws_record = apr_palloc(r->pool, sizeof *ws_record); for (i = 0; i < server_limit; ++i) { + volatile process_score *ps; #ifdef HAVE_TIMES clock_t proc_tu = 0, proc_ts = 0, proc_tcu = 0, proc_tcs = 0; clock_t tmp_tu, tmp_ts, tmp_tcu, tmp_tcs; #endif - ps_record = ap_get_scoreboard_process(i); + ps = ap_get_scoreboard_process(i); + proc_buffer[i].pid = ps->pid; + proc_buffer[i].gen = ps->generation; if (is_async) { thread_idle_buffer[i] = 0; thread_graceful_buffer[i] = 0; @@ -328,7 +336,12 @@ static int status_handler(request_rec *r) for (j = 0; j < thread_limit; ++j) { int indx = (i * thread_limit) + j; - ap_copy_scoreboard_worker(ws_record, i, j); + if (proc_buffer[i].pid) { + ap_copy_scoreboard_worker(ws_record, i, j); + } + else { + memset(ws_record, 0, sizeof(*ws_record)); + } res = ws_record->status; if ((i >= max_servers || j >= threads_per_child) @@ -337,10 +350,10 @@ static int status_handler(request_rec *r) else stat_buffer[indx] = status_flags[res]; - if (!ps_record->quiescing - && ps_record->pid) { + if (proc_buffer[i].pid + && !ps->quiescing) { if (res == SERVER_READY) { - if (ps_record->generation == mpm_generation) + if (proc_buffer[i].gen == mpm_generation) idle++; if (is_async) thread_idle_buffer[i]++; @@ -410,7 +423,6 @@ static int status_handler(request_rec *r) tcu += proc_tcu; tcs += proc_tcs; #endif - pid_buffer[i] = ps_record->pid; } /* up_time in seconds */ @@ -420,20 +432,21 @@ static int status_handler(request_rec *r) if (!short_report) { ap_rputs(DOCTYPE_HTML_4_01 - "\n" + "\n\n" "Apache Status\n" - "\n" + "\n\n" "

Apache Server Status for ", r); ap_rvputs(r, ap_escape_html(r->pool, ap_get_server_name(r)), " (via ", r->connection->local_ip, - ")

\n\n", NULL); - ap_rvputs(r, "
Server Version: ", + ")\n", NULL); + ap_rvputs(r, "
\n
Server Version: ", ap_get_server_description(), "
\n", NULL); - ap_rvputs(r, "
Server MPM: ", - ap_show_mpm(), "
\n", NULL); ap_rvputs(r, "
Server Built: ", - ap_get_server_built(), "\n

\n", NULL); - ap_rvputs(r, "
Current Time: ", + ap_get_server_built(), "
\n", NULL); + ap_rvputs(r, "
Server MPM: ", + ap_show_mpm(), "
\n
\n" + "
\n", NULL); + ap_rvputs(r, "
\n
Current Time: ", ap_ht_time(r->pool, nowtime, DEFAULT_TIME_FORMAT, 0), "
\n", NULL); ap_rvputs(r, "
Restart Time: ", @@ -561,91 +574,134 @@ static int status_handler(request_rec *r) ap_rprintf(r, "BusyWorkers: %d\nGracefulWorkers: %d\nIdleWorkers: %d\n", busy, graceful, idle); if (!short_report) - ap_rputs("
", r); + ap_rputs("
\n", r); if (is_async) { - int reading = 0, writing = 0, lingering_close = 0, keep_alive = 0, - connections = 0, stopping = 0, procs = 0; + apr_uint32_t procs = 0, stopping = 0, accepting = 0, + connections = 0, backlog = 0, reading = 0, writing = 0, + keep_alive = 0, flushing = 0, closing = 0; if (!short_report) - ap_rputs("\n\n\n" - "" - "" - "" - "\n" - "" - "\n" - "" - "" - "\n", r); + ap_rputs("
SlotPIDStoppingConnectionsThreadsAsync connections
totalacceptingbusygracefulidlereadingwritingkeep-aliveclosing
\n" + "" + "" + "" + "\n" + "" + "" + "" + "" + "\n", + r); + ps_record = apr_pcalloc(r->pool, sizeof *ps_record); for (i = 0; i < server_limit; ++i) { - ps_record = ap_get_scoreboard_process(i); - if (ps_record->pid) { + if (proc_buffer[i].pid) { + volatile process_score *ps = ap_get_scoreboard_process(i); + ps_record->pid = ps->pid; + ps_record->generation = ps->generation; + ps_record->quiescing = ps->quiescing; + ps_record->not_accepting = ps->not_accepting; + apr_atomic_set32(&ps_record->connections, + apr_atomic_read32(&ps->connections)); + apr_atomic_set32(&ps_record->backlog, + apr_atomic_read32(&ps->backlog)); + apr_atomic_set32(&ps_record->reading, + apr_atomic_read32(&ps->reading)); + apr_atomic_set32(&ps_record->write_completion, + apr_atomic_read32(&ps->write_completion)); + apr_atomic_set32(&ps_record->keep_alive, + apr_atomic_read32(&ps->keep_alive)); + apr_atomic_set32(&ps_record->flushing, + apr_atomic_read32(&ps->flushing)); + apr_atomic_set32(&ps_record->lingering_close, + apr_atomic_read32(&ps->lingering_close)); + connections += ps_record->connections; + backlog += ps_record->backlog; reading += ps_record->reading; writing += ps_record->write_completion; keep_alive += ps_record->keep_alive; - lingering_close += ps_record->lingering_close; + flushing += ps_record->flushing; + closing += ps_record->lingering_close; procs++; if (ps_record->quiescing) { stopping++; } + if (!ps_record->not_accepting) { + accepting++; + } if (!short_report) { const char *dying = "no"; const char *old = ""; + const char *listening = "yes"; if (ps_record->quiescing) { dying = "yes"; } - if (ps_record->generation != mpm_generation) + if (ps_record->generation != mpm_generation) { old = " (old gen)"; + } + if (ps_record->not_accepting) { + listening = "no"; + } ap_rprintf(r, "" - "" - "" - "" - "" - "\n", + "" + "" + "" + "" + "\n", i, ps_record->pid, - dying, old, - ps_record->connections, - ps_record->not_accepting ? "no" : "yes", + dying, old, listening, thread_busy_buffer[i], - thread_graceful_buffer[i], thread_idle_buffer[i], + thread_graceful_buffer[i], + ps_record->connections, + ps_record->backlog, ps_record->reading, ps_record->write_completion, ps_record->keep_alive, + ps_record->flushing, ps_record->lingering_close); } } } if (!short_report) { ap_rprintf(r, "" - "" - "" - "" - "" - "\n
ProcessesThreadsConnectionsAsync queues
SlotPIDstoppingacceptingbusyidlegracefultotalbacklogreadingwritingkeep-aliveflushingclosing
%u%" APR_PID_T_FMT "%s%s%u%s%u%u%u%u%u%u%u
%s%s%s%d%d%d%u%u%u%u%u%u%u
Sum%d%d%d %d%d%d%d%d%d%d
\n", - procs, stopping, - connections, - busy, graceful, idle, - reading, writing, keep_alive, lingering_close); + "%u%u%u" + "%u%u%u" + "%u%u" + "%u%u" + "%u%u%u\n" + "\n", + procs, stopping, accepting, + busy, idle, graceful, + connections, backlog, + reading, writing, + keep_alive, flushing, closing); } else { - ap_rprintf(r, "Processes: %d\n" - "Stopping: %d\n" - "ConnsTotal: %d\n" - "ConnsAsyncReading: %d\n" - "ConnsAsyncWriting: %d\n" - "ConnsAsyncKeepAlive: %d\n" - "ConnsAsyncClosing: %d\n", - procs, stopping, - connections, - reading, writing, keep_alive, lingering_close); + ap_rprintf(r, "Processes: %u\n" + "Stopping: %u\n" + "Accepting: %u\n" + "ThreadsBusy: %u\n" + "ThreadsIdle: %u\n" + "ThreadsGraceful: %u\n" + "ConnsTotal: %u\n" + "ConnsBacklog: %u\n" + "ConnsAsyncReading: %u\n" + "ConnsAsyncWriting: %u\n" + "ConnsAsyncKeepAlive: %u\n" + "ConnsAsyncFlushing: %u\n" + "ConnsAsyncClosing: %u\n", + procs, stopping, accepting, + busy, idle, graceful, + connections, backlog, + reading, writing, + keep_alive, flushing, closing); } } /* send the scoreboard 'table' out */ if (!short_report) - ap_rputs("
", r);
+        ap_rputs("
\n", r);
     else
         ap_rputs("Scoreboard: ", r);
 
@@ -667,7 +723,7 @@ static int status_handler(request_rec *r)
     if (short_report)
         ap_rputs("\n", r);
     else {
-        ap_rputs("
\n" + ap_rputs("\n
\n" "

Scoreboard Key:
\n" "\"_\" Waiting for Connection, \n" "\"S\" Starting up, \n" @@ -684,17 +740,18 @@ static int status_handler(request_rec *r) if (!ap_extended_status) { int j; int k = 0; - ap_rputs("PID Key:
\n" + ap_rputs("

PID Key:
\n" "

\n", r);
             for (i = 0; i < server_limit; ++i) {
+                if (!proc_buffer[i].pid) {
+                    continue;
+                }
                 for (j = 0; j < thread_limit; ++j) {
                     int indx = (i * thread_limit) + j;
 
-                    if (stat_buffer[indx] != '.') {
-                        ap_rprintf(r, "   %" APR_PID_T_FMT
-                                   " in state: %c ", pid_buffer[i],
-                                   stat_buffer[indx]);
-
+                    if (stat_buffer[indx] != status_flags[SERVER_DISABLED]) {
+                        ap_rprintf(r, "  %8" APR_PID_T_FMT " in state: %c ",
+                                   proc_buffer[i].pid, stat_buffer[indx]);
                         if (++k >= 3) {
                             ap_rputs("\n", r);
                             k = 0;
@@ -703,17 +760,16 @@ static int status_handler(request_rec *r)
                     }
                 }
             }
-
-            ap_rputs("\n"
-                     "
\n", r); + ap_rvputs(r, k ? "\n" : "", "\n", "

\n", NULL); } } if (ap_extended_status && !short_report) { if (no_table_report) - ap_rputs("

Server Details

\n\n", r); + ap_rputs("
\n

Server Details

\n", r); else - ap_rputs("\n\n" + ap_rputs("
\n" + "
" "" "" #ifdef HAVE_TIMES @@ -722,9 +778,13 @@ static int status_handler(request_rec *r) "" "" "" - "\n\n", r); + "\n", r); for (i = 0; i < server_limit; ++i) { + if (!proc_buffer[i].pid) { + continue; + } + for (j = 0; j < thread_limit; ++j) { ap_copy_scoreboard_worker(ws_record, i, j); @@ -734,8 +794,6 @@ static int status_handler(request_rec *r) continue; } - ps_record = ap_get_scoreboard_process(i); - if (ws_record->start_time == 0L) req_time = 0L; else @@ -757,8 +815,8 @@ static int status_handler(request_rec *r) worker_generation = ws_record->generation; } else { - worker_pid = ps_record->pid; - worker_generation = ps_record->generation; + worker_pid = proc_buffer[i].pid; + worker_generation = proc_buffer[i].gen; } if (no_table_report) { @@ -836,7 +894,7 @@ static int status_handler(request_rec *r) format_byte_out(r, bytes); ap_rputs(")\n", r); ap_rprintf(r, - " %s {%s}(%s)[%s]
\n\n", + " %s {%s}(%s)[%s]
\n", ap_escape_html(r->pool, ws_record->client64), ap_escape_html(r->pool, @@ -923,7 +981,7 @@ static int status_handler(request_rec *r) (float)bytes / MBYTE); ap_rprintf(r, "" - "\n\n", + "\n", ap_escape_html(r->pool, ws_record->client64), ap_escape_html(r->pool, @@ -939,7 +997,7 @@ static int status_handler(request_rec *r) if (!no_table_report) { ap_rputs("
SrvPIDAccMSSReqDurConnChildSlotClientProtocolVHostRequest
Request
%s%s%s%s
%s
\n \ -
\ +

\n \ \n \ \n \ \n \ @@ -956,13 +1014,15 @@ static int status_handler(request_rec *r) \n \ \n \ \n \ -
SrvChild Server number - generation
PIDOS process ID
ConnKilobytes transferred this connection
ChildMegabytes transferred this child
SlotTotal megabytes transferred this slot
\n", r); +\n \ +

", r); } } /* if (ap_extended_status && !short_report) */ else { if (!short_report) { - ap_rputs("
To obtain a full report with current status " + ap_rputs("
\n" + "To obtain a full report with current status " "information you need to use the " "ExtendedStatus On directive.\n", r); } @@ -980,7 +1040,7 @@ static int status_handler(request_rec *r) if (!short_report) { ap_rputs(ap_psignature("
\n",r), r); - ap_rputs("\n", r); + ap_rputs("\n\n", r); } return 0;