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