You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by pq...@apache.org on 2009/11/12 16:05:10 UTC

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

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);



Re: 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

Posted by pqf <pq...@mailtech.cn>.
Hi, Jeff
   Thank you for the code style reference, I will follow this style next time :)
   Actually there are many space for extra info(like vhost), and we can just put this in the share memeory and output it through /server_status, but another issue is system security, I think we should not provide too much internal info to client(file full path, user id etc). So I now just output the info that "nobody" can get through "ps -ef". But if it's no harm, please feel free to add more info to the share memory.

Thanks

--------------------------------------------------
From: "Jeff Trawick" <tr...@gmail.com>
Sent: Friday, November 13, 2009 5:08 AM
To: <de...@httpd.apache.org>
Subject: Re: 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

> On Thu, Nov 12, 2009 at 10:05 AM,  <pq...@apache.org> wrote:
>> 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
> 
> Hi Ryan,
> 
> This looks extremely useful.  Hopefully I can look at it more over the
> next few days.  At first glance I think the process heading needs more
> information, such as the vhost or other attributes that distinguish
> the table from other tables for the same executable file, since
> otherwise it may be unexpected to see multiple tables for the same
> program, each with its own set of processes.
> 
> For anyone that wants a quick look at the information, I've uploaded a
> sample page to
> 
> http://people.apache.org/~trawick/mod_fcgid_status.html
> 
> Thanks!
> 
> BTW, I made some code formatting changes in r835540 to bring the new
> mod_status code closer to httpd project style (guidelines are at
> http://httpd.apache.org/dev/styleguide.html, examples for issues not
> covered there are throughout httpd).
> 

Re: 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

Posted by Jeff Trawick <tr...@gmail.com>.
On Thu, Nov 12, 2009 at 10:05 AM,  <pq...@apache.org> wrote:
> 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

Hi Ryan,

This looks extremely useful.  Hopefully I can look at it more over the
next few days.  At first glance I think the process heading needs more
information, such as the vhost or other attributes that distinguish
the table from other tables for the same executable file, since
otherwise it may be unexpected to see multiple tables for the same
program, each with its own set of processes.

For anyone that wants a quick look at the information, I've uploaded a
sample page to

http://people.apache.org/~trawick/mod_fcgid_status.html

Thanks!

BTW, I made some code formatting changes in r835540 to bring the new
mod_status code closer to httpd project style (guidelines are at
http://httpd.apache.org/dev/styleguide.html, examples for issues not
covered there are throughout httpd).