You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modules-dev@httpd.apache.org by John David Duncan <jd...@mysql.com> on 2007/02/23 18:46:41 UTC

Per-server config issue

Hi,

I am seeing a very strange issue with per-server config processing.

Consider a config directive:

{  "ServerThing",
     (CMD_HAND_TYPE) config_server_thing,
     NULL,
     RSRC_CONF,      TAKE1,
     "For Testing"
}

I have a struct to hold the per-server configuration (struct srv).   
An instance of struct srv gets allocated and initialized by an init  
function, and then when Apache sees "ServerThing foo" in httpd.conf,  
it calls config_server_thing:

const char *config_server_thing(cmd_parms *cmd, void *m, char *arg) {

}

So far, so good.  But here's the problem:  In this function, I should  
be able to cast the pointer, m, back to the struct srv that was  
initialized earlier.

  srv_conf = (struct srv *) m;

But after lots of debugging, I find that:

   1) The pointer m is not equal to the pointer that was returned  
from the initialization function.
   2) m does not hold a copy of the data structure that was initialized.
   3) And m is also not equal to the value of
        ap_get_module_config(cmd->server->module_config, &my_module)

Finally, as a work-around, I decided to use:
   srv_conf = (struct srv *) ap_get_module_config(cmd->server- 
 >module_config, &my_module);
instead of:
   srv_conf = (struct srv *) m;


So, what's the problem?  Well...
  * It's not a "merge" problem.  (I implemented a merging function  
just in case, but that never gets called).
  * It's not the vhost issue described on pg. 574 of "Writing Apache  
Modules with Perl and C" where your init function might never get  
called (the init function *is* called, and there are no virtual hosts  
at all in this config file)
  * It's not a bug with one particular release of Apache -- I see the  
same behavior in both 1.3.33 and 2.2.3.
  * I can't find any obvious problem with my code (all of my per- 
directory config stuff works perfectly).


So, I wonder: is my work-around safe?
Should I file a bug?
Is there someone in particular I should ask for help?


Thanks,

JD


Re: Per-server config issue

Posted by David Wortham <dj...@gmail.com>.
JD,
   I ran into the same problem/issue that you are observing.  I was not able
to effectively use a casted version of the (void*) parameter.
ap_get_module_config(...) works fine for me.

   To clarify some of the questions you have:
- Server config inits are run when the httpd.conf is read (at server
startup) and when .htaccess files are read (at the beginning of each
request).
- Anything created at server startup is created by the parent httpd process;
then at the end of startup, all parent config data is cloned for each child
process (explaining why you see different pointers for what you thought was
the same pointer)

This link may help you understand the Apache startup better:
http://www.f-m-c.org/projects/apache/html/3_3Extending_Apache.html

Sorry if I'm telling you something you already know, but this info would
have helped me immensely when I started module programming.

Dave





On 2/23/07, John David Duncan <jd...@mysql.com> wrote:
>
> Hi,
>
> I am seeing a very strange issue with per-server config processing.
>
> Consider a config directive:
>
> {  "ServerThing",
>      (CMD_HAND_TYPE) config_server_thing,
>      NULL,
>      RSRC_CONF,      TAKE1,
>      "For Testing"
> }
>
> I have a struct to hold the per-server configuration (struct srv).
> An instance of struct srv gets allocated and initialized by an init
> function, and then when Apache sees "ServerThing foo" in httpd.conf,
> it calls config_server_thing:
>
> const char *config_server_thing(cmd_parms *cmd, void *m, char *arg) {
>
> }
>
> So far, so good.  But here's the problem:  In this function, I should
> be able to cast the pointer, m, back to the struct srv that was
> initialized earlier.
>
>   srv_conf = (struct srv *) m;
>
> But after lots of debugging, I find that:
>
>    1) The pointer m is not equal to the pointer that was returned
> from the initialization function.
>    2) m does not hold a copy of the data structure that was initialized.
>    3) And m is also not equal to the value of
>         ap_get_module_config(cmd->server->module_config, &my_module)
>
> Finally, as a work-around, I decided to use:
>    srv_conf = (struct srv *) ap_get_module_config(cmd->server-
> >module_config, &my_module);
> instead of:
>    srv_conf = (struct srv *) m;
>
>
> So, what's the problem?  Well...
>   * It's not a "merge" problem.  (I implemented a merging function
> just in case, but that never gets called).
>   * It's not the vhost issue described on pg. 574 of "Writing Apache
> Modules with Perl and C" where your init function might never get
> called (the init function *is* called, and there are no virtual hosts
> at all in this config file)
>   * It's not a bug with one particular release of Apache -- I see the
> same behavior in both 1.3.33 and 2.2.3.
>   * I can't find any obvious problem with my code (all of my per-
> directory config stuff works perfectly).
>
>
> So, I wonder: is my work-around safe?
> Should I file a bug?
> Is there someone in particular I should ask for help?
>
>
> Thanks,
>
> JD
>
>

Re: Per-server config issue

Posted by John David Duncan <jd...@mysql.com>.
Joe Lewis & David Wortham,

Thanks for helping to clarify this murky issue last week!

JD


> The void *m parameter is only set if the function is being called  
> in a <Directory> block, in which case it will be assigned to that  
> directory block's configuration that you create, not the servers'  
> configuration structure. If it is a server directive (as yours is  
> in the examples you provided) this parameter should be NULL.


Re: Per-server config issue

Posted by Joe Lewis <jo...@joe-lewis.com>.
John David Duncan wrote:
> const char *config_server_thing(cmd_parms *cmd, void *m, char *arg) {
>
> }
>
> So far, so good. But here's the problem: In this function, I should be 
> able to cast the pointer, m, back to the struct srv that was 
> initialized earlier.
>
> srv_conf = (struct srv *) m;
>
> But after lots of debugging, I find that:
>
> 1) The pointer m is not equal to the pointer that was returned from 
> the initialization function.
> 2) m does not hold a copy of the data structure that was initialized.
> 3) And m is also not equal to the value of
> ap_get_module_config(cmd->server->module_config, &my_module)
>
> Finally, as a work-around, I decided to use:
> srv_conf = (struct srv *) 
> ap_get_module_config(cmd->server->module_config, &my_module);
> instead of:
> srv_conf = (struct srv *) m;

The void *m parameter is only set if the function is being called in a 
<Directory> block, in which case it will be assigned to that directory 
block's configuration that you create, not the servers' configuration 
structure. If it is a server directive (as yours is in the examples you 
provided) this parameter should be NULL.

I have a few functions that are both directory specific and also server 
specific (used in both circumstances), and to prevent a redesign of the 
wheel, I typically check for NULL on that parameter, and if it is NULL, 
I reassign it to the cmd->server->module_config option - giving me a 
valid configuration structure as I created both. Then I am free to do 
what I want with it.

Joe
-- 
Joseph Lewis <http://sharktooth.org/>
"Divide the fire, and you will sooner put it out." - Publius Syrus