httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From p..@apache.org
Subject svn commit: r835406 - in /httpd/mod_fcgid/trunk/modules/fcgid: fcgid_pm_main.c fcgid_proc_unix.c fcgid_proc_win.c fcgid_proctbl.h mod_fcgid.c
Date Thu, 12 Nov 2009 15:05:10 GMT
Author: pqf
Date: Thu Nov 12 15:05:08 2009
New Revision: 835406

URL: http://svn.apache.org/viewvc?rev=835406&view=rev
Log:
Add fcgid extension to mod_status

Modified:
    httpd/mod_fcgid/trunk/modules/fcgid/fcgid_pm_main.c
    httpd/mod_fcgid/trunk/modules/fcgid/fcgid_proc_unix.c
    httpd/mod_fcgid/trunk/modules/fcgid/fcgid_proc_win.c
    httpd/mod_fcgid/trunk/modules/fcgid/fcgid_proctbl.h
    httpd/mod_fcgid/trunk/modules/fcgid/mod_fcgid.c

Modified: httpd/mod_fcgid/trunk/modules/fcgid/fcgid_pm_main.c
URL: http://svn.apache.org/viewvc/httpd/mod_fcgid/trunk/modules/fcgid/fcgid_pm_main.c?rev=835406&r1=835405&r2=835406&view=diff
==============================================================================
--- httpd/mod_fcgid/trunk/modules/fcgid/fcgid_pm_main.c (original)
+++ httpd/mod_fcgid/trunk/modules/fcgid/fcgid_pm_main.c Thu Nov 12 15:05:08 2009
@@ -226,7 +226,7 @@
         next_node = &proc_table[current_node->next_index];
 
         /* Is it zombie process? */
-        thepid = current_node->proc_id->pid;
+        thepid = current_node->proc_id.pid;
         if (proc_wait_process(main_server, current_node) == APR_CHILD_DONE) {
             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, main_server,
                          "mod_fcgid: cleanup zombie process %"
@@ -331,7 +331,7 @@
             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, main_server,
                          "mod_fcgid: process %" APR_PID_T_FMT
                          " graceful kill fail, sending SIGKILL",
-                         current_node->proc_id->pid);
+                         current_node->proc_id.pid);
             proc_kill_force(current_node, main_server);
         }
     }
@@ -366,7 +366,7 @@
     /* Kill with SIGKILL if it doesn't work */
     for (i = 0; i < proctable_get_table_size(); i++) {
         if (proc_table[i].proc_pool) {
-            if (apr_proc_wait(proc_table[i].proc_id, &exitcode, &exitwhy,
+            if (apr_proc_wait(&(proc_table[i].proc_id), &exitcode, &exitwhy,
                               APR_NOWAIT) != APR_CHILD_NOTDONE) {
                 proc_table[i].diewhy = FCGID_DIE_SHUTDOWN;
                 proc_print_exit_info(&proc_table[i], exitcode, exitwhy,
@@ -381,7 +381,7 @@
     /* Wait again */
     for (i = 0; i < proctable_get_table_size(); i++) {
         if (proc_table[i].proc_pool) {
-            if (apr_proc_wait(proc_table[i].proc_id, &exitcode, &exitwhy,
+            if (apr_proc_wait(&(proc_table[i].proc_id), &exitcode, &exitwhy,
                               APR_WAIT) != APR_CHILD_NOTDONE) {
                 proc_table[i].diewhy = FCGID_DIE_SHUTDOWN;
                 proc_print_exit_info(&proc_table[i], exitcode, exitwhy,
@@ -548,7 +548,7 @@
                           procnode, proctable_array);
         ap_log_error(APLOG_MARK, APLOG_INFO, 0, main_server,
                      "mod_fcgid: server %s:%s(%" APR_PID_T_FMT ") started",
-                     command->virtualhost, command->cgipath, procnode->proc_id->pid);
+                     command->virtualhost, command->cgipath, procnode->proc_id.pid);
         register_spawn(main_server, procnode);
     }
 }

Modified: httpd/mod_fcgid/trunk/modules/fcgid/fcgid_proc_unix.c
URL: http://svn.apache.org/viewvc/httpd/mod_fcgid/trunk/modules/fcgid/fcgid_proc_unix.c?rev=835406&r1=835405&r2=835406&view=diff
==============================================================================
--- httpd/mod_fcgid/trunk/modules/fcgid/fcgid_proc_unix.c (original)
+++ httpd/mod_fcgid/trunk/modules/fcgid/fcgid_proc_unix.c Thu Nov 12 15:05:08 2009
@@ -63,7 +63,6 @@
 } fcgid_namedpipe_handle;
 
 static int g_process_counter = 0;
-static apr_pool_t *g_inode_cginame_map = NULL;
 
 static apr_status_t ap_unix_create_privileged_process(apr_proc_t *newproc,
                                                       const char *progname,
@@ -179,6 +178,7 @@
                                                     &fcgid_module);
     apr_status_t rv = APR_SUCCESS;
     apr_file_t *file;
+    apr_proc_t tmpproc;
     int omask, retcode, unix_socket;
     char **proc_environ;
     struct sockaddr_un unix_addr;
@@ -204,18 +204,6 @@
     }
     wargv[argc] = NULL;
 
-    /* Initialize the variables */
-    if (!g_inode_cginame_map) {
-        rv = apr_pool_create(&g_inode_cginame_map,
-                             procinfo->main_server->process->pconf);
-        if (rv != APR_SUCCESS) {
-            ap_log_error(APLOG_MARK, APLOG_WARNING, rv,
-                         procinfo->main_server,
-                         "mod_fcgid: can't create CGI name map table");
-            return APR_ENOMEM;
-        }
-    }
-
     /* 
        Create UNIX domain socket before spawn 
      */
@@ -229,6 +217,8 @@
                  getpid(), g_process_counter++);
     strncpy(procnode->socket_path, unix_addr.sun_path,
             sizeof(procnode->socket_path) - 1);
+    strncpy(procnode->executable_path, (lpszwapper!=NULL && lpszwapper[0]!='\0')?wargv[0]:procinfo->cgipath,
+            sizeof(procnode->executable_path) - 1);
 
     /* Unlink the file just in case */
     unlink(unix_addr.sun_path);
@@ -327,8 +317,6 @@
     }
 
     /* Prepare the fork */
-    procnode->proc_id = apr_pcalloc(procnode->proc_pool, 
-                                    sizeof(apr_proc_t));
     if (
    (rv =
     apr_procattr_create(&procattr, procnode->proc_pool)) != APR_SUCCESS
@@ -361,12 +349,15 @@
     }
 
     /* fork and exec now */
+    /* Note, don't pass &(procnode->proc_id) to fcgid_create_privileged_process(),
+    for it's a share memory address, both parent and child process may modify 
+    procnode->proc_id->pid, so sometimes it's 0 and sometimes it's >0 */
     if (lpszwapper != NULL && lpszwapper[0] != '\0') {
         ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, procinfo->main_server,
                      "mod_fcgid: call %s with wrapper %s",
                      procinfo->cgipath, lpszwapper);
         if ((rv =
-             fcgid_create_privileged_process(procnode->proc_id,
+             fcgid_create_privileged_process(&tmpproc,
                                              wargv[0], wargv,
                                              (const char *const *)
                                              proc_environ, procattr,
@@ -377,13 +368,14 @@
                          "mod_fcgid: can't create wrapper process for %s",
                          procinfo->cgipath);
             close(unix_socket);
+            procnode->proc_id = tmpproc;
             return rv;
         }
     } else {
         argv[0] = procinfo->cgipath;
         argv[1] = NULL;
         if ((rv =
-             fcgid_create_privileged_process(procnode->proc_id,
+             fcgid_create_privileged_process(&tmpproc,
                                              procinfo->cgipath,
                                              argv,
                                              (const char *const *)
@@ -394,31 +386,14 @@
             ap_log_error(APLOG_MARK, APLOG_ERR, rv, procinfo->main_server,
                          "mod_fcgid: can't create process");
             close(unix_socket);
+            procnode->proc_id = tmpproc;
             return rv;
         }
     }
 
-    /* Set the (deviceid, inode) -> fastcgi path map for log */
-    apr_snprintf(key_name, _POSIX_PATH_MAX, "%lX%lX",
-                 (unsigned long) procnode->inode,
-                 (unsigned long) procnode->deviceid);
-    dummy = NULL;
-    apr_pool_userdata_get(&dummy, key_name, g_inode_cginame_map);
-    if (!dummy) {
-        /* Insert a new item if key not found */
-        const char *put_key = apr_psprintf(g_inode_cginame_map, "%lX%lX",
-                                           (unsigned long) procnode->inode,
-                                           (unsigned long) procnode->deviceid);
-        const char *fcgipath = apr_psprintf(g_inode_cginame_map, "%s",
-                                            procinfo->cgipath);
-
-        if (put_key && fcgipath)
-            apr_pool_userdata_set(fcgipath, put_key, NULL,
-                                  g_inode_cginame_map);
-    }
-
     /* Close socket before try to connect to it */
     close(unix_socket);
+    procnode->proc_id = tmpproc;
 
     return APR_SUCCESS;
 }
@@ -436,7 +411,7 @@
         kill(getpid(), SIGTERM);
         return APR_EACCES;
     }
-    rv = apr_proc_kill(procnode->proc_id, SIGTERM);
+    rv = apr_proc_kill(&(procnode->proc_id), SIGTERM);
     if (ap_unixd_config.suexec_enabled && seteuid(ap_unixd_config.user_id) != 0)
     {
         kill(getpid(), SIGTERM);
@@ -456,7 +431,7 @@
         kill(getpid(), SIGTERM);
         return APR_EACCES;
     }
-    rv = apr_proc_kill(procnode->proc_id, SIGKILL);
+    rv = apr_proc_kill(&(procnode->proc_id), SIGKILL);
     if (ap_unixd_config.suexec_enabled && seteuid(ap_unixd_config.user_id) != 0)
     {
         kill(getpid(), SIGTERM);
@@ -472,7 +447,7 @@
     int exitcode;
     apr_exit_why_e exitwhy;
 
-    rv = apr_proc_wait(procnode->proc_id, &exitcode, &exitwhy, APR_NOWAIT);
+    rv = apr_proc_wait(&(procnode->proc_id), &exitcode, &exitwhy, APR_NOWAIT);
     if (rv == APR_CHILD_DONE || rv == APR_EGENERAL) {
         /* Log why and how it die */
         proc_print_exit_info(procnode, exitcode, exitwhy, main_server);
@@ -831,7 +806,6 @@
 proc_print_exit_info(fcgid_procnode * procnode, int exitcode,
                      apr_exit_why_e exitwhy, server_rec * main_server)
 {
-    const char *cgipath = NULL;
     const char *diewhy = NULL;
     char signal_info[HUGE_STRING_LEN];
     char key_name[_POSIX_PATH_MAX];
@@ -840,14 +814,6 @@
 
     memset(signal_info, 0, HUGE_STRING_LEN);
 
-    /* Get the file name infomation base on inode and deviceid */
-    apr_snprintf(key_name, _POSIX_PATH_MAX, "%lX%lX",
-                 (unsigned long) procnode->inode,
-                 (unsigned long) procnode->deviceid);
-    apr_pool_userdata_get(&tmp, key_name,
-                          g_inode_cginame_map);
-    cgipath = tmp;
-
     /* Reasons to exit */
     switch (procnode->diewhy) {
     case FCGID_DIE_KILLSELF:
@@ -905,12 +871,7 @@
     }
 
     /* Print log now */
-    if (cgipath)
-        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
-                     "mod_fcgid: process %s(%" APR_PID_T_FMT ") exit(%s), %s",
-                     cgipath, procnode->proc_id->pid, diewhy, signal_info);
-    else
-        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
-                     "mod_fcgid: can't get CGI name while exiting, exitcode: %d",
-                     exitcode);
+    ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
+                 "mod_fcgid: process %s(%" APR_PID_T_FMT ") exit(%s), %s",
+                 procnode->executable_path, procnode->proc_id.pid, diewhy, signal_info);
 }

Modified: httpd/mod_fcgid/trunk/modules/fcgid/fcgid_proc_win.c
URL: http://svn.apache.org/viewvc/httpd/mod_fcgid/trunk/modules/fcgid/fcgid_proc_win.c?rev=835406&r1=835405&r2=835406&view=diff
==============================================================================
--- httpd/mod_fcgid/trunk/modules/fcgid/fcgid_proc_win.c (original)
+++ httpd/mod_fcgid/trunk/modules/fcgid/fcgid_proc_win.c Thu Nov 12 15:05:08 2009
@@ -49,7 +49,6 @@
 } fcgid_namedpipe_handle;
 
 static int g_process_counter = 0;
-static apr_pool_t *g_inode_cginame_map = NULL;
 
 static apr_status_t close_finish_event(void *finishevent)
 {
@@ -69,9 +68,7 @@
     apr_status_t rv;
     apr_file_t *file;
     char **proc_environ;
-    char key_name[_POSIX_PATH_MAX];
     char sock_path[_POSIX_PATH_MAX];
-    char *dummy;
     char *argv[2];
     int argc;
     char *wargv[APACHE_ARG_MAX], *word; /* For wrapper */
@@ -92,18 +89,6 @@
 
     memset(&SecurityAttributes, 0, sizeof(SecurityAttributes));
 
-    /* Create the pool if necessary */
-    if (!g_inode_cginame_map) {
-        rv = apr_pool_create(&g_inode_cginame_map,
-                             procinfo->main_server->process->pconf);
-        if (rv != APR_SUCCESS) {
-            ap_log_error(APLOG_MARK, APLOG_WARNING, rv,
-                         procinfo->main_server,
-                         "mod_fcgid: can't create CGI name map table");
-            return APR_ENOMEM;
-        }
-    }
-
     /* Prepare finish event */
     finish_event = apr_palloc(procnode->proc_pool, sizeof(HANDLE));
     *finish_event = CreateEvent(NULL, TRUE, FALSE, NULL);
@@ -146,7 +131,9 @@
                      "mod_fcgid: can't create namedpipe for subprocess");
         return APR_ENOSOCKET;
     }
-    apr_cpystrn(procnode->socket_path, sock_path, _POSIX_PATH_MAX);
+    apr_cpystrn(procnode->socket_path, sock_path, sizeof(procnode->socket_path) - 1);
+    apr_cpystrn(procnode->executable_path, (wrapper_cmdline!=NULL && wrapper_cmdline[0]!='\0')?wargv[0]:procinfo->cgipath,
+            sizeof(procnode->executable_path) - 1);
 
     /* Build environment variables */
     proc_environ = ap_create_environment(procnode->proc_pool,
@@ -159,8 +146,6 @@
     }
 
     /* Create process now */
-    procnode->proc_id = apr_pcalloc(procnode->proc_pool,
-                                    sizeof(apr_proc_t));
     if ((rv = apr_procattr_create(&proc_attr, procnode->proc_pool))
                != APR_SUCCESS
         || (rv = apr_procattr_dir_set(proc_attr,
@@ -188,7 +173,7 @@
         ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, procinfo->main_server,
                      "mod_fcgid: call %s with wrapper %s",
                      procinfo->cgipath, wrapper_cmdline);
-        if ((rv = apr_proc_create(procnode->proc_id, wargv[0],
+        if ((rv = apr_proc_create(&(procnode->proc_id), wargv[0],
                                   wargv, proc_environ, proc_attr,
                                   procnode->proc_pool)) != APR_SUCCESS) {
             ap_log_error(APLOG_MARK, APLOG_ERR, rv, procinfo->main_server,
@@ -201,7 +186,7 @@
         argv[0] = procinfo->cgipath;
         argv[1] = NULL;
         if ((rv =
-             apr_proc_create(procnode->proc_id, procinfo->cgipath,
+             apr_proc_create(&(procnode->proc_id), procinfo->cgipath,
                              argv, proc_environ, proc_attr,
                              procnode->proc_pool)) != APR_SUCCESS) {
             ap_log_error(APLOG_MARK, APLOG_ERR, rv, procinfo->main_server,
@@ -214,25 +199,6 @@
     /* OK, I created the process, now put it back to idle list */
     CloseHandle(listen_handle);
 
-    /* Set the (deviceid, inode, shareid) -> fastcgi path map for log */
-    apr_snprintf(key_name, _POSIX_PATH_MAX, "%lX%lX%lX",
-                 procnode->inode, procnode->deviceid,
-                 procnode->share_grp_id);
-    dummy = NULL;
-    apr_pool_userdata_get(&dummy, key_name, g_inode_cginame_map);
-    if (!dummy) {
-        /* Insert a new item if key not found */
-        char *put_key = apr_psprintf(g_inode_cginame_map, "%lX%lX%lX",
-                                     procnode->inode, procnode->deviceid,
-                                     procnode->share_grp_id);
-        char *fcgipath = apr_psprintf(g_inode_cginame_map, "%s",
-                                      procinfo->cgipath);
-
-        if (put_key && fcgipath)
-            apr_pool_userdata_set(fcgipath, put_key, NULL,
-                                  g_inode_cginame_map);
-    }
-
     return APR_SUCCESS;
 }
 
@@ -252,7 +218,7 @@
 apr_status_t proc_kill_force(fcgid_procnode *procnode,
                              server_rec *main_server)
 {
-    return apr_proc_kill(procnode->proc_id, SIGKILL);
+    return apr_proc_kill(&(procnode->proc_id), SIGKILL);
 }
 
 apr_status_t proc_wait_process(server_rec *main_server,
@@ -262,7 +228,7 @@
     int exitcode;
     apr_exit_why_e exitwhy;
 
-    if ((rv = apr_proc_wait(procnode->proc_id, &exitcode, &exitwhy,
+    if ((rv = apr_proc_wait(&(procnode->proc_id), &exitcode, &exitwhy,
                             APR_NOWAIT)) == APR_CHILD_DONE) {
         /* Log why and how it die */
         proc_print_exit_info(procnode, exitcode, exitwhy, main_server);
@@ -350,13 +316,13 @@
             ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, ipc_handle->request,
                           "mod_fcgid: can't connect to named pipe, FastCGI"
                           " server %" APR_PID_T_FMT " has been terminated",
-                          procnode->proc_id->pid);
+                          procnode->proc_id.pid);
         else
             ap_log_rerror(APLOG_MARK, APLOG_DEBUG, apr_get_os_error(), 
                           ipc_handle->request,
                           "mod_fcgid: can't connect to named pipe, FastCGI"
                           " server pid %" APR_PID_T_FMT,
-                          procnode->proc_id->pid);
+                          procnode->proc_id.pid);
         return APR_ESPIPE;
     }
 
@@ -506,15 +472,7 @@
 void proc_print_exit_info(fcgid_procnode * procnode, int exitcode,
                           apr_exit_why_e exitwhy, server_rec * main_server)
 {
-    char *cgipath = NULL;
     char *diewhy = NULL;
-    char key_name[_POSIX_PATH_MAX];
-
-    /* Get the file name infomation base on inode and deviceid */
-    apr_snprintf(key_name, _POSIX_PATH_MAX, "%lX%lX%lX",
-                 procnode->inode, procnode->deviceid,
-                 procnode->share_grp_id);
-    apr_pool_userdata_get(&cgipath, key_name, g_inode_cginame_map);
 
     /* Reasons to exit */
     switch (procnode->diewhy) {
@@ -547,12 +505,7 @@
     }
 
     /* Print log now */
-    if (cgipath)
-        ap_log_error(APLOG_MARK, APLOG_INFO, 0, main_server,
+    ap_log_error(APLOG_MARK, APLOG_INFO, 0, main_server,
                      "mod_fcgid: process %s(%" APR_PID_T_FMT ") exit(%s), return code %d",
-                     cgipath, procnode->proc_id->pid, diewhy, exitcode);
-    else
-        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, main_server,
-                     "mod_fcgid: can't get CGI name while exiting, exitcode: %d",
-                     exitcode);
+                     procnode->executable_path, procnode->proc_id.pid, diewhy, exitcode);
 }

Modified: httpd/mod_fcgid/trunk/modules/fcgid/fcgid_proctbl.h
URL: http://svn.apache.org/viewvc/httpd/mod_fcgid/trunk/modules/fcgid/fcgid_proctbl.h?rev=835406&r1=835405&r2=835406&view=diff
==============================================================================
--- httpd/mod_fcgid/trunk/modules/fcgid/fcgid_proctbl.h (original)
+++ httpd/mod_fcgid/trunk/modules/fcgid/fcgid_proctbl.h Thu Nov 12 15:05:08 2009
@@ -37,9 +37,13 @@
     4) error list: a process is associated, and killing the process now
 */
 typedef struct {
+    union {
     int next_index;             /* the next array index in the list */
+    int node_type;              /* the type of this node, used in fcgid_status_hook() only
*/
+    };
     apr_pool_t *proc_pool;      /* pool for process */
-    apr_proc_t *proc_id;        /* the process id */
+    apr_proc_t proc_id;        /* the process id */
+    char executable_path[_POSIX_PATH_MAX]; /* executable file path */
     char socket_path[_POSIX_PATH_MAX];  /* cgi application socket path */
     apr_ino_t inode;            /* cgi file inode */
     apr_dev_t deviceid;         /* cgi file device id */

Modified: httpd/mod_fcgid/trunk/modules/fcgid/mod_fcgid.c
URL: http://svn.apache.org/viewvc/httpd/mod_fcgid/trunk/modules/fcgid/mod_fcgid.c?rev=835406&r1=835405&r2=835406&view=diff
==============================================================================
--- httpd/mod_fcgid/trunk/modules/fcgid/mod_fcgid.c (original)
+++ httpd/mod_fcgid/trunk/modules/fcgid/mod_fcgid.c Thu Nov 12 15:05:08 2009
@@ -22,6 +22,7 @@
 #include "apr_buckets.h"
 #include "apr_thread_proc.h"
 #include "mod_cgi.h"
+#include "mod_status.h"
 #include "util_script.h"
 #include "fcgid_global.h"
 #include "fcgid_pm.h"
@@ -31,11 +32,19 @@
 #include "fcgid_bridge.h"
 #include "fcgid_filter.h"
 #include "fcgid_protocol.h"
+#include "fcgid_proc.h"
 
 static APR_OPTIONAL_FN_TYPE(ap_cgi_build_command) * cgi_build_command;
 static ap_filter_rec_t *fcgid_filter_handle;
 static int g_php_fix_pathinfo_enable = 0;
 
+enum fcgid_procnode_type
+{
+    FCGID_PROCNODE_TYPE_IDLE,
+    FCGID_PROCNODE_TYPE_BUSY,
+    FCGID_PROCNODE_TYPE_ERROR,
+};
+
 /* Stolen from mod_cgi.c */
 /* KLUDGE --- for back-compatibility, we don't have to check ExecCGI
  * in ScriptAliased directories, which means we need to know if this
@@ -228,6 +237,182 @@
     return (http_retcode == HTTP_OK ? OK : http_retcode);
 }
 
+static int fcgidsort(fcgid_procnode **e1, fcgid_procnode **e2)
+{
+    int cmp = strcmp((*e1)->executable_path, (*e2)->executable_path);
+    if( cmp!=0 )
+        return cmp;
+    if( (*e1)->gid!=(*e2)->gid )
+        return (*e1)->gid>(*e2)->gid?1:-1;
+    if( (*e1)->uid!=(*e2)->uid )
+        return (*e1)->uid>(*e2)->uid?1:-1;
+    if( (*e1)->share_grp_id!=(*e2)->share_grp_id )
+        return (*e1)->share_grp_id>(*e2)->share_grp_id?1:-1;
+    if( (*e1)->virtualhost!=(*e2)->virtualhost )
+        return (*e1)->virtualhost>(*e2)->virtualhost?1:-1;
+    if( (*e1)->diewhy!=(*e2)->diewhy )
+        return (*e1)->diewhy>(*e2)->diewhy?1:-1;
+    if( (*e1)->node_type!=(*e2)->node_type )
+        return (*e1)->node_type>(*e2)->node_type?1:-1;
+    return 0;
+}
+
+static char* get_state_desc(fcgid_procnode* node)
+{
+    if( node->node_type==FCGID_PROCNODE_TYPE_IDLE )
+        return "Ready";
+    else if( node->node_type==FCGID_PROCNODE_TYPE_BUSY )
+        return "Working";
+    else
+    {
+        switch (node->diewhy) {
+        case FCGID_DIE_KILLSELF:
+            return "Exiting(normal exit)";
+        case FCGID_DIE_IDLE_TIMEOUT:
+            return "Exiting(idle timeout)";
+        case FCGID_DIE_LIFETIME_EXPIRED:
+            return "Exiting(lifetime expired)";
+        case FCGID_DIE_BUSY_TIMEOUT:
+            return "Exiting(busy timeout)";
+        case FCGID_DIE_CONNECT_ERROR:
+            return "Exiting(connect error)";
+        case FCGID_DIE_COMM_ERROR:
+            return "Exiting(communication error)";
+        case FCGID_DIE_SHUTDOWN:
+            return "Exiting(shutting down)";
+        default:
+            return "Exiting";
+        }
+    }
+}
+    
+/* fcgid Extension to mod_status */
+int fcgid_status_hook(request_rec *r, int flags)
+{       
+    fcgid_procnode **ar, *current_node;
+    int num_ent, index;
+    apr_ino_t last_inode = 0;
+    apr_dev_t last_deviceid = 0;
+    gid_t last_gid = 0;  
+    uid_t last_uid = 0;
+    apr_size_t last_share_grp_id = 0;
+    const char *last_virtualhost = NULL;
+    char* basename, *tmpbasename;
+    fcgid_procnode *proc_table = proctable_get_table_array();
+    fcgid_procnode *error_list_header = proctable_get_error_list();
+    fcgid_procnode *idle_list_header = proctable_get_idle_list();
+    fcgid_procnode *busy_list_header = proctable_get_busy_list();
+        
+    if( (flags&AP_STATUS_SHORT) || (proc_table==NULL) )
+        return OK;
+            
+    proctable_lock(r);
+        
+    /* Get element count */
+    num_ent = 0;
+    current_node = &proc_table[busy_list_header->next_index];
+    while (current_node != proc_table)
+    {
+        num_ent++;
+        current_node = &proc_table[current_node->next_index];
+    }
+    current_node = &proc_table[idle_list_header->next_index];
+    while (current_node != proc_table)
+    {
+        num_ent++;
+        current_node = &proc_table[current_node->next_index];
+    }
+    current_node = &proc_table[error_list_header->next_index];
+    while (current_node != proc_table)
+    {
+        num_ent++;
+        current_node = &proc_table[current_node->next_index];
+    }
+
+    /* Create an array for qsort() */
+    if( num_ent!=0 )
+    {   
+        ar = (fcgid_procnode **) apr_palloc(r->pool, num_ent * sizeof(fcgid_procnode*));
+        index = 0;
+        current_node = &proc_table[busy_list_header->next_index];
+        while (current_node != proc_table)
+        {   
+            ar[index] = apr_palloc(r->pool, sizeof(fcgid_procnode));
+            *ar[index] = *current_node;
+            ar[index++]->node_type = FCGID_PROCNODE_TYPE_BUSY;
+            current_node = &proc_table[current_node->next_index];
+        }
+        current_node = &proc_table[idle_list_header->next_index];
+        while (current_node != proc_table)
+        {   
+            ar[index] = apr_palloc(r->pool, sizeof(fcgid_procnode));
+            *ar[index] = *current_node;
+            ar[index++]->node_type = FCGID_PROCNODE_TYPE_IDLE;
+            current_node = &proc_table[current_node->next_index];
+        }    
+        current_node = &proc_table[error_list_header->next_index];
+        while (current_node != proc_table)
+        {   
+            ar[index] = apr_palloc(r->pool, sizeof(fcgid_procnode));
+            *ar[index] = *current_node;
+            ar[index++]->node_type = FCGID_PROCNODE_TYPE_ERROR;
+            current_node = &proc_table[current_node->next_index];
+        }
+    }
+    proctable_unlock(r);
+
+    /* Sort the array */
+    if( num_ent!=0 )
+        qsort((void *) ar, num_ent, sizeof(fcgid_procnode*), (int (*)(const void *, const
void *)) fcgidsort);
+    
+    /* Output */
+    ap_rprintf(r, "<hr />\n<h1>Total FastCGI process: %d</h1>\n", num_ent);
+    for( index=0; index<num_ent; index++ )
+    {
+    	current_node = ar[index];
+        if( current_node->inode!=last_inode || current_node->deviceid!=last_deviceid
+            || current_node->gid!=last_gid || current_node->uid!=last_uid
+            || current_node->share_grp_id!=last_share_grp_id
+            || current_node->virtualhost!=last_virtualhost )
+        {
+            if( index!=0 )
+                 ap_rputs("</table>\n\n", r);
+           
+            /* Print executable path basename */
+	    tmpbasename = ap_strrchr_c(current_node->executable_path, '/');
+	    if (tmpbasename != NULL)
+                tmpbasename++;
+            basename = ap_strrchr_c(tmpbasename, '\\');
+            if( basename!=NULL )
+                basename++;
+	    else
+                basename = tmpbasename;
+            ap_rprintf(r, "<hr />\n<h3>Process name: %s</h3>\n", basename);
+
+            /* Create a new table for this process info */
+            ap_rputs("\n\n<table border=\"0\"><tr>"
+                 "<th>pid</th><th>Process start time</th><th>Last
active time</th><th>Request handled</th><th>State</th>"
+                 "</tr>\n", r);
+
+            last_inode = current_node->inode;
+            last_deviceid = current_node->deviceid;
+            last_gid = current_node->gid;
+            last_uid = current_node->uid;
+            last_share_grp_id = current_node->share_grp_id;
+            last_virtualhost = current_node->virtualhost;
+        }
+
+        ap_rprintf(r, "<tr><td>%" APR_PID_T_FMT "</td><td>%" APR_TIME_T_FMT
"</td><td>%" APR_TIME_T_FMT "</td><td>%d</td><td>%s</td></tr>",
+            current_node->proc_id.pid, apr_time_sec(current_node->start_time),
+            apr_time_sec(current_node->last_active_time), current_node->requests_handled,
+            get_state_desc(current_node));
+    }
+    if( num_ent!=0 )
+        ap_rputs("</table>\n\n", r);
+
+    return OK;
+}
+
 static int mod_fcgid_modify_auth_header(void *subprocess_env,
                                         const char *key, const char *val)
 {
@@ -773,8 +958,17 @@
     {NULL}
 };
 
+static int fcgid_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
+                            apr_pool_t *ptemp)
+{                            
+    APR_OPTIONAL_HOOK(ap, status_hook, fcgid_status_hook, NULL, NULL,
+                      APR_HOOK_MIDDLE);
+    return OK;
+} 
+
 static void register_hooks(apr_pool_t * p)
 {
+    ap_hook_pre_config(fcgid_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
     ap_hook_post_config(fcgid_init, NULL, NULL, APR_HOOK_MIDDLE);
     ap_hook_child_init(initialize_child, NULL, NULL, APR_HOOK_MIDDLE);
     ap_hook_handler(fcgid_handler, NULL, NULL, APR_HOOK_MIDDLE);



Mime
View raw message