
pqf at apache
Nov 12, 2009, 7:05 AM
Post #1 of 1
(178 views)
Permalink
|
|
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);
|