ASF Bugzilla – Attachment 22316 Details for
Bug 43494
mod_cgid does not kill never ending scripts
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Adding a timeout watch for mod_cgid (first cut)
patch (text/plain), 5.06 KB, created by
rahul
on 2008-07-25 05:33:15 UTC
(
hide
)
Description:
Adding a timeout watch for mod_cgid (first cut)
Filename:
MIME Type:
Creator:
rahul
Created:
2008-07-25 05:33:15 UTC
Size:
5.06 KB
patch
obsolete
>Index: mod_cgid.c >=================================================================== >--- mod_cgid.c (revision 679776) >+++ mod_cgid.c (working copy) >@@ -35,6 +35,9 @@ > #include "apr_buckets.h" > #include "apr_optional.h" > #include "apr_signal.h" >+#include "apr_time.h" >+#include "apr_thread_proc.h" >+#include "apr_thread_mutex.h" > > #define APR_WANT_STRFUNC > #include "apr_want.h" >@@ -185,6 +188,12 @@ > int loglevel; /* to stuff in server_rec */ > } cgid_req_t; > >+ >+#define EXPIRE_CHECK_INTERVAL 15L * 1000L * 1000L >+static apr_hash_t *cgi_pid_hash; >+static apr_thread_mutex_t *cgi_pid_lock; >+static apr_time_t cgi_timeout; >+ > /* This routine is called to create the argument list to be passed > * to the CGI script. When suexec is enabled, the suexec path, user, and > * group are the first three arguments to be passed; if not, all three >@@ -564,6 +573,67 @@ > ap_log_error(APLOG_MARK, APLOG_ERR, err, r->server, "%s", description); > } > >+static void cgiwatcher_add(pid_t pid, apr_pool_t *pool) { >+ pid_t *key = apr_palloc(pool, sizeof(pid_t)); >+ memcpy(key, &pid, sizeof(pid_t)); >+ >+ apr_time_t *val = apr_palloc(pool, sizeof(apr_time_t)); >+ /* when the timeout will happen*/ >+ apr_time_t last = apr_time_now() + cgi_timeout; >+ memcpy(val, &last, sizeof(apr_time_t)); >+ >+ apr_thread_mutex_lock(cgi_pid_lock); >+ apr_hash_set(cgi_pid_hash, key, sizeof(apr_time_t),val); >+ apr_thread_mutex_unlock(cgi_pid_lock); >+} >+ >+static void cgiwatcher_remove(pid_t pid) { >+ apr_thread_mutex_lock(cgi_pid_lock); >+ /* TODO: How does the key and value allocated get reclaimed? */ >+ apr_hash_set(cgi_pid_hash, &pid, 0, (void*)0); >+ apr_thread_mutex_unlock(cgi_pid_lock); >+} >+ >+static void check_child(pid_t pid, apr_time_t time, apr_pool_t *pool) { >+ apr_time_t rem = time - apr_time_now(); >+ ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, pool, "cgiwatcher: on the loop for cgi [%d] (%d)", pid, apr_time_sec(rem)); >+ >+ if (time < apr_time_now()) { /* timed out..*/ >+ ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, pool, "cgiwatcher: killed cgi [%d]", pid); >+ kill(pid, SIGHUP); >+ } >+} >+ >+static void * APR_THREAD_FUNC cgiwatcher(apr_thread_t *thd, void *data) >+{ >+ apr_hash_index_t *hi; >+ apr_pool_t *pool_iter; >+ apr_pool_create(&pool_iter, pcgi); >+ while(!daemon_should_exit) { >+ apr_thread_mutex_lock(cgi_pid_lock); >+ for (hi = apr_hash_first(pool_iter, cgi_pid_hash); hi; hi = apr_hash_next(hi)) { >+ pid_t *key; >+ apr_ssize_t len; >+ apr_time_t *val; >+ apr_hash_this(hi, (void*)&key, &len, (void*)&val); >+ if (!val) continue; >+ check_child(*key, *val, pool_iter); >+ /* cleanup script will take out the entry from the hash.*/ >+ } >+ apr_thread_mutex_unlock(cgi_pid_lock); >+ apr_pool_clear(pool_iter); >+ apr_sleep(EXPIRE_CHECK_INTERVAL); >+ } >+} >+ >+static apr_status_t setup_timeout_thread(apr_pool_t *pool) >+{ >+ apr_thread_mutex_create(&cgi_pid_lock, APR_THREAD_MUTEX_DEFAULT, pcgi); >+ cgi_pid_hash = apr_hash_make(pcgi); >+ apr_thread_t *timeout_thread; >+ return apr_thread_create(&timeout_thread, NULL, cgiwatcher, pcgi, pcgi); >+} >+ > static int cgid_server(void *data) > { > struct sockaddr_un unix_addr; >@@ -631,6 +701,14 @@ > return errno; > } > } >+ >+ /* Set up the thread to watch for timeout */ >+ rv = setup_timeout_thread(pcgi); >+ if(rv != APR_SUCCESS) { >+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, main_server, >+ "Couldn't start the cgiwatcher thread."); >+ return rv; >+ } > > unixd_setup_child(); /* if running as root, switch to configured user/group */ > >@@ -700,6 +778,12 @@ > "Error writing pid %" APR_PID_T_FMT " to handler", pid); > } > close(sd2); >+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, >+ main_server, >+ "cgiwatcher: remove pid from list %d", pid); >+ >+ /* GETPID request is initiated by the cleanup script which means the pid is no longer alive.*/ >+ cgiwatcher_remove(pid); > continue; > } > >@@ -782,6 +866,11 @@ > apr_filepath_name_get(r->filename)); > > procnew->pid = 0; /* no process to clean up */ >+ } else { >+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, >+ "cgiwatcher: Adding process to timeout list: %d: %s", procnew->pid, >+ apr_filepath_name_get(r->filename)); >+ cgiwatcher_add(procnew->pid, pcgi); > } > } > >@@ -818,6 +907,10 @@ > { > > daemon_should_exit = 0; /* clear setting from previous generation */ >+ cgi_timeout = main_server->timeout; >+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, >+ "cgiwatcher: timeout - %" APR_TIME_T_FMT ".", main_server->timeout); >+ > if ((daemon_pid = fork()) < 0) { > ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server, > "mod_cgid: Couldn't spawn cgid daemon process");
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 43494
:
22316
|
22324
|
30110