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