rse 98/03/06 04:52:59
Modified: src CHANGES
src/modules/standard mod_rewrite.c mod_rewrite.h
Log:
Avoid the flock()<->fork() problematic by giving each child an
own file descriptor instead of a shared one.
Revision Changes Path
1.692 +11 -0 apache-1.3/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
retrieving revision 1.691
retrieving revision 1.692
diff -u -r1.691 -r1.692
--- CHANGES 1998/03/06 09:37:04 1.691
+++ CHANGES 1998/03/06 12:52:55 1.692
@@ -1,5 +1,16 @@
Changes with Apache 1.3b6
+ *) Fix one more special locking problem for RewriteMap programs in
+ mod_rewrite: According to the documentation of flock(), "Locks are on
+ files, not file descriptors. That is, file descriptors duplicated
+ through dup(2) or fork(2) do not result in multiple instances of a lock,
+ but rather multiple references to a single lock. If a process holding a
+ lock on a file forks and the child explicitly unlocks the file, the
+ parent will lose its lock.". To overcome this we have to make sure the
+ RewriteLock file is opened _AFTER_ the childs were spawned which is now
+ the case by opening it in the child_init instead of the module_init API
+ hook. [Ralf S. Engelschall, PR#1029]
+
*) Change to Location and LocationMatch semantics. LocationMatch no
longer lets a single slash match multiple adjacent slashes in the
URL. This change is for consistency with RewriteRule and
1.87 +86 -29 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.86
retrieving revision 1.87
diff -u -r1.86 -r1.87
--- mod_rewrite.c 1998/03/05 12:42:37 1.86
+++ mod_rewrite.c 1998/03/06 12:52:57 1.87
@@ -193,7 +193,7 @@
hook_fixup, /* [#7] pre-run fixups */
NULL, /* [#9] log a transaction */
NULL, /* [#3] header parser */
- NULL, /* child_init */
+ init_child, /* child_init */
NULL, /* child_exit */
NULL /* [#0] post read-request */
};
@@ -869,7 +869,7 @@
/*
**
-** module initialisation
+** Global Module Initialization
** [called from read_config() after all
** config commands were already called]
**
@@ -877,26 +877,42 @@
static void init_module(server_rec *s, pool *p)
{
+ /* check if proxy module is available */
+ proxy_available = is_proxy_available(s);
+
+ /* precompile a static pattern
+ for the txt mapfile parsing */
+ lookup_map_txtfile_regexp = pregcomp(p, MAPFILE_PATTERN, REG_EXTENDED);
+
+ /* create the rewriting lockfile in the parent */
+ rewritelock_create(s, p);
+ register_cleanup(p, (void *)s, rewritelock_remove, null_cleanup);
+
/* 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);
}
+}
- /* create the lookup cache */
- cachep = init_cache(p);
- /* check if proxy module is available */
- proxy_available = is_proxy_available(s);
+/*
+**
+** Per-Child Module Initialization
+** [called after a child process is spawned]
+**
+*/
- /* precompile a static pattern
- for the txt mapfile parsing */
- lookup_map_txtfile_regexp = pregcomp(p, MAPFILE_PATTERN, REG_EXTENDED);
+static void init_child(server_rec *s, pool *p)
+{
+ /* open the rewriting lockfile */
+ rewritelock_open(s, p);
+
+ /* create the lookup cache */
+ cachep = init_cache(p);
}
@@ -2984,37 +3000,78 @@
** +-------------------------------------------------------+
*/
-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 );
+#define REWRITELOCK_MODE ( _S_IREAD|_S_IWRITE )
#else
- mode_t rewritelock_mode = ( S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH );
+#define REWRITELOCK_MODE ( S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH )
#endif
+static void rewritelock_create(server_rec *s, pool *p)
+{
+ rewrite_server_conf *conf;
+
conf = get_module_config(s->module_config, &rewrite_module);
- if (conf->rewritelockfile == NULL)
- return;
- if (*(conf->rewritelockfile) == '\0')
+ /* only operate if a lockfile is used */
+ if (conf->rewritelockfile == NULL
+ || *(conf->rewritelockfile) == '\0')
return;
- if (conf->rewritelockfp > 0)
- return; /* virtual log shared w/ main server */
- fname = server_root_relative(p, conf->rewritelockfile);
+ /* fixup the path, especially for rewritelock_remove() */
+ conf->rewritelockfile = server_root_relative(p, conf->rewritelockfile);
- if ((conf->rewritelockfp = popenf(p, fname, rewritelock_flags,
- rewritelock_mode)) < 0) {
+ /* create the lockfile */
+ unlink(conf->rewritelockfile);
+ if ((conf->rewritelockfp = popenf(p, conf->rewritelockfile,
+ O_WRONLY|O_CREAT,
+ REWRITELOCK_MODE)) < 0) {
perror("open");
- fprintf(stderr,
- "mod_rewrite: could not open RewriteLock file %s.\n",
- fname);
+ fprintf(stderr, "mod_rewrite: Parent could not create RewriteLock"
+ " file %s.\n", conf->rewritelockfile);
exit(1);
}
return;
+}
+
+static void rewritelock_open(server_rec *s, pool *p)
+{
+ rewrite_server_conf *conf;
+
+ conf = get_module_config(s->module_config, &rewrite_module);
+
+ /* only operate if a lockfile is used */
+ if (conf->rewritelockfile == NULL
+ || *(conf->rewritelockfile) == '\0')
+ return;
+
+ /* open the lockfile (once per child) to get a unique fd */
+ if ((conf->rewritelockfp = popenf(p, conf->rewritelockfile,
+ O_WRONLY,
+ REWRITELOCK_MODE)) < 0) {
+ perror("open");
+ fprintf(stderr, "mod_rewrite: Child could not open RewriteLock"
+ " file %s.\n", conf->rewritelockfile);
+ exit(1);
+ }
+ return;
+}
+
+static void rewritelock_remove(void *data)
+{
+ server_rec *s;
+ rewrite_server_conf *conf;
+
+ /* the data is really the server_rec */
+ s = (server_rec *)data;
+ conf = get_module_config(s->module_config, &rewrite_module);
+
+ /* only operate if a lockfile is used */
+ if (conf->rewritelockfile == NULL
+ || *(conf->rewritelockfile) == '\0')
+ return;
+
+ /* remove the lockfile */
+ unlink(conf->rewritelockfile);
}
static void rewritelock_alloc(request_rec *r)
1.47 +4 -1 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.46
retrieving revision 1.47
diff -u -r1.46 -r1.47
--- mod_rewrite.h 1998/03/05 10:45:24 1.46
+++ mod_rewrite.h 1998/03/06 12:52:58 1.47
@@ -375,6 +375,7 @@
/* initialisation */
static void init_module(server_rec *s, pool *p);
+static void init_child(server_rec *s, pool *p);
/* runtime hooks */
static int hook_uri2file (request_rec *r);
@@ -425,7 +426,9 @@
static char *current_logtime(request_rec *r);
/* rewriting lockfile support */
-static void open_rewritelock(server_rec *s, pool *p);
+static void rewritelock_create(server_rec *s, pool *p);
+static void rewritelock_open(server_rec *s, pool *p);
+static void rewritelock_remove(void *data);
static void rewritelock_alloc(request_rec *r);
static void rewritelock_free(request_rec *r);