rse 98/02/24 05:39:12
Modified: src CHANGES htdocs/manual/mod mod_rewrite.html src/modules/standard mod_rewrite.c mod_rewrite.h Log: First part to fix the synchronization-locking for RewriteMap programs under Unix derivates who doesn't accept the locking of pipes directly. But we perhaps have another problem: According to FreeBSD's manpage and a hint by the submitter of PR#1029 flock() has to be used on opened filedescriptors which are _not_ duplicated via fork(). This currently is not the case... Submitted by: Ralf S. Engelschall Reviewed by: Ralf S. Engelschall, Jim Jagielski Revision Changes Path 1.666 +6 -0 apache-1.3/src/CHANGES Index: CHANGES =================================================================== RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v retrieving revision 1.665 retrieving revision 1.666 diff -u -r1.665 -r1.666 --- CHANGES 1998/02/24 12:40:55 1.665 +++ CHANGES 1998/02/24 13:39:05 1.666 @@ -1,5 +1,11 @@ Changes with Apache 1.3b6 + *) Fix long-standing problem with RewriteMap _programs_ under Unix derivates + (like SunOS and FreeBSD) which don't accept the locking of pipes + directly. A new directive RewriteLock is introduced which can be used to + setup a separate locking file which then is used for synchronization. + [Ralf S. Engelschall, PR#1029] + *) WIN32: The server root is obtained from the registry key HKLM\SOFTWARE\Apache Group\Apache\<version> (version is currently "1.3 beta"), unless overridden by the -d command line flag. The 1.24 +32 -2 apache-1.3/htdocs/manual/mod/mod_rewrite.html Index: mod_rewrite.html =================================================================== RCS file: /export/home/cvs/apache-1.3/htdocs/manual/mod/mod_rewrite.html,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- mod_rewrite.html 1998/02/23 08:27:36 1.23 +++ mod_rewrite.html 1998/02/24 13:39:08 1.24 @@ -68,6 +68,7 @@ <LI><A HREF="#RewriteOptions">RewriteOptions</A> <LI><A HREF="#RewriteLog">RewriteLog</A> <LI><A HREF="#RewriteLogLevel">RewriteLogLevel</A> + <LI><A HREF="#RewriteLock">RewriteLock</A> <LI><A HREF="#RewriteMap">RewriteMap</A> <LI><A HREF="#RewriteBase">RewriteBase</A> <LI><A HREF="#RewriteCond">RewriteCond</A> @@ -252,6 +253,32 @@ <hr noshade size=1> <P> +<H3><A NAME="RewriteLock">RewriteLock</A></H3> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> <CODE>RewriteLock</CODE> <EM>Filename</EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> -<EM>None</EM>-<BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<P> + +This directive sets the filename for a synchronization lockfile which +mod_rewrite needs to communicate with <SAMP>RewriteMap</SAMP> +<EM>programs</EM>. Set this lockfile to a local path (not on a NFS-mounted +device) when you want to use a rewriting map-program. It is not required for +SAMP +using all other types of rewriting maps. + +<P> +<hr noshade size=1> +<P> + <H3><A NAME="RewriteMap">RewriteMap</A></H3> <A HREF="directive-dict.html#Syntax" @@ -437,8 +464,11 @@ if this program hangs it will lead to a hang of the Apache server when the rule occurs. <LI>Avoid one common mistake: never do buffered I/O on <TT>stdout</TT>! - This will cause a deadloop! Hence the ``<TT>$|=1</TT>'' in the above - example... + This will cause a deadloop! Hence the ``<TT>$|=1</TT>'' in the above + example... + <LI>Use the <SAMP>RewriteLock</SAMP> directive to define a lockfile + mod_rewrite can use to synchronize the communication to the program. + Per default no such synchronization takes place. </OL> </UL> 1.69 +109 -22 apache-1.3/src/modules/standard/mod_rewrite.c Index: mod_rewrite.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_rewrite.c,v retrieving revision 1.68 retrieving revision 1.69 diff -u -r1.68 -r1.69 --- mod_rewrite.c 1998/02/23 15:18:50 1.68 +++ mod_rewrite.c 1998/02/24 13:39:10 1.69 @@ -112,9 +112,6 @@ /* now our own stuff ... */ #include "mod_rewrite.h" -#ifdef USE_LOCKING -#include <sys/locking.h> -#endif /* @@ -172,6 +169,8 @@ "a URL-applied regexp-pattern and a substitution URL" }, { "RewriteMap", cmd_rewritemap, NULL, RSRC_CONF, TAKE2, "a mapname and a filename" }, + { "RewriteLock", cmd_rewritelock, NULL, RSRC_CONF, TAKE1, + "the filename of a lockfile used for inter-process synchronization"}, { "RewriteLog", cmd_rewritelog, NULL, RSRC_CONF, TAKE1, "the filename of the rewriting logfile" }, { "RewriteLogLevel", cmd_rewriteloglevel, NULL, RSRC_CONF, TAKE1, @@ -250,6 +249,8 @@ a->rewritelogfile = NULL; a->rewritelogfp = -1; a->rewriteloglevel = 1; + a->rewritelockfile = NULL; + a->rewritelockfp = -1; a->rewritemaps = make_array(p, 2, sizeof(rewritemap_entry)); a->rewriteconds = make_array(p, 2, sizeof(rewritecond_entry)); a->rewriterules = make_array(p, 2, sizeof(rewriterule_entry)); @@ -272,6 +273,10 @@ a->rewritelogfp = base->rewritelogfp != -1 ? base->rewritelogfp : overrides->rewritelogfp; a->rewriteloglevel = overrides->rewriteloglevel; + a->rewritelockfile = base->rewritelockfile != NULL ? + base->rewritelockfile : overrides->rewritelockfile; + a->rewritelockfp = base->rewritelockfp != -1 ? + base->rewritelockfp : overrides->rewritelockfp; if (a->options & OPTION_INHERIT) { a->rewritemaps = append_arrays(p, overrides->rewritemaps, @@ -490,6 +495,18 @@ return NULL; } +static const char *cmd_rewritelock(cmd_parms *cmd, void *dconf, char *a1) +{ + rewrite_server_conf *sconf; + + sconf = (rewrite_server_conf *) + get_module_config(cmd->server->module_config, &rewrite_module); + + sconf->rewritelockfile = a1; + + return NULL; +} + static const char *cmd_rewritebase(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *a1) { @@ -856,10 +873,12 @@ { /* step through the servers and * - open each rewriting logfile + * - open each rewriting lockfile * - open the RewriteMap prg:xxx programs */ for (; s; s = s->next) { open_rewritelog(s, p); + open_rewritelock(s, p); run_rewritemap_programs(s, p); } @@ -2635,10 +2654,8 @@ char c; int i; - /* lock the channel */ -#ifdef USE_PIPE_LOCKING - fd_lock(fpin); -#endif + /* take the lock */ + rewritelock_alloc(r); /* write out the request key */ write(fpin, key, strlen(key)); @@ -2653,10 +2670,8 @@ } buf[i] = '\0'; - /* unlock the channel */ -#ifdef USE_PIPE_LOCKING - fd_unlock(fpin); -#endif + /* give the lock back */ + rewritelock_free(r); if (strcasecmp(buf, "NULL") == 0) return NULL; @@ -2775,7 +2790,7 @@ if (*(conf->rewritelogfile) == '\0') return; if (conf->rewritelogfp > 0) - return; /* virtual log shared w/main server */ + return; /* virtual log shared w/ main server */ fname = server_root_relative(p, conf->rewritelogfile); @@ -2923,6 +2938,70 @@ /* ** +-------------------------------------------------------+ ** | | +** | rewriting lockfile support +** | | +** +-------------------------------------------------------+ +*/ + +static void open_rewritelock(server_rec *s, pool *p) +{ + rewrite_server_conf *conf; + char *fname; + int rewritelock_flags = ( O_WRONLY|O_APPEND|O_CREAT ); +#ifdef WIN32 + mode_t rewritelock_mode = ( _S_IREAD|_S_IWRITE ); +#else + mode_t rewritelock_mode = ( S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH ); +#endif + + conf = get_module_config(s->module_config, &rewrite_module); + + if (conf->rewritelockfile == NULL) + return; + if (*(conf->rewritelockfile) == '\0') + return; + if (conf->rewritelockfp > 0) + return; /* virtual log shared w/ main server */ + + fname = server_root_relative(p, conf->rewritelockfile); + + if ((conf->rewritelockfp = popenf(p, fname, rewritelock_flags, + rewritelock_mode)) < 0) { + perror("open"); + fprintf(stderr, + "mod_rewrite: could not open RewriteLock file %s.\n", + fname); + exit(1); + } + return; +} + +static void rewritelock_alloc(request_rec *r) +{ + rewrite_server_conf *conf; + + conf = get_module_config(r->server->module_config, &rewrite_module); + + if (conf->rewritelockfp != -1) + fd_lock(conf->rewritelockfp); + return; +} + +static void rewritelock_free(request_rec *r) +{ + rewrite_server_conf *conf; + + conf = get_module_config(r->server->module_config, &rewrite_module); + + if (conf->rewritelockfp != -1) + fd_unlock(conf->rewritelockfp); + return; +} + + +/* +** +-------------------------------------------------------+ +** | | ** | program map support ** | | ** +-------------------------------------------------------+ @@ -3789,18 +3868,22 @@ #ifdef USE_LOCKING /* Lock the first byte, always, assume we want to append and seek to the end afterwards */ - lseek(fd,0,SEEK_SET); - rc=_locking(fd, _LK_LOCK, 1); - lseek(fd,0,SEEK_END); + lseek(fd, 0, SEEK_SET); + rc = _locking(fd, _LK_LOCK, 1); + lseek(fd, 0, SEEK_END); #endif if (rc < 0) { #ifdef USE_FLOCK perror("flock"); -#else +#endif +#ifdef USE_FCNTL perror("fcntl"); #endif - fprintf(stderr, "Error getting lock. Exiting!"); +#ifdef USE_LOCKING + perror("_locking"); +#endif + fprintf(stderr, "mod_rewrite: Error getting lock. Exiting!"); exit(1); } return; @@ -3823,18 +3906,22 @@ rc = flock(fd, LOCK_UN); #endif #ifdef USE_LOCKING - lseek(fd,0,SEEK_SET); - rc=_locking(fd,_LK_UNLCK,1); - lseek(fd,0,SEEK_END); + lseek(fd, 0, SEEK_SET); + rc = _locking(fd, _LK_UNLCK, 1); + lseek(fd, 0, SEEK_END); #endif if (rc < 0) { #ifdef USE_FLOCK perror("flock"); -#else +#endif +#ifdef USE_FCNTL perror("fcntl"); #endif - fprintf(stderr, "Error freeing lock. Exiting!"); +#ifdef USE_LOCKING + perror("_locking"); +#endif + fprintf(stderr, "mod_rewrite: Error freeing lock. Exiting!"); exit(1); } } 1.38 +10 -9 apache-1.3/src/modules/standard/mod_rewrite.h Index: mod_rewrite.h =================================================================== RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_rewrite.h,v retrieving revision 1.37 retrieving revision 1.38 diff -u -r1.37 -r1.38 --- mod_rewrite.h 1998/02/23 08:27:39 1.37 +++ mod_rewrite.h 1998/02/24 13:39:11 1.38 @@ -136,17 +136,9 @@ #ifdef WIN32 #undef USE_FCNTL #define USE_LOCKING +#include <sys/locking.h> #endif - /* The locking support for the RewriteMap programs: - * Locking a pipe to the child works fine under most - * Unix derivates, but braindead SunOS 4.1.x has - * problems with this approach... - */ -#define USE_PIPE_LOCKING 1 -#ifdef SUNOS4 -#undef USE_PIPE_LOCKING -#endif /* ** @@ -265,6 +257,8 @@ char *rewritelogfile; /* the RewriteLog filename */ int rewritelogfp; /* the RewriteLog open filepointer */ int rewriteloglevel; /* the RewriteLog level of verbosity */ + char *rewritelockfile; /* the RewriteLock filename */ + int rewritelockfp; /* the RewriteLock open filepointer */ array_header *rewritemaps; /* the RewriteMap entries */ array_header *rewriteconds; /* the RewriteCond entries (temporary) */ array_header *rewriterules; /* the RewriteRule entries */ @@ -339,6 +333,8 @@ static const char *cmd_rewritemap (cmd_parms *cmd, void *dconf, char *a1, char *a2); +static const char *cmd_rewritelock(cmd_parms *cmd, void *dconf, char *a1); + static const char *cmd_rewritebase(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *a1); @@ -409,6 +405,11 @@ static void rewritelog(request_rec *r, int level, const char *text, ...) __attribute__((format(printf,3,4))); static char *current_logtime(request_rec *r); + + /* rewritinf lockfile support */ +static void open_rewritelock(server_rec *s, pool *p); +static void rewritelock_alloc(request_rec *r); +static void rewritelock_free(request_rec *r); /* program map support */ static void run_rewritemap_programs(server_rec *s, pool *p);