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 dave <ma...@gmail.com> on 2009/02/10 23:29:20 UTC

Re: WELCOME to modules-dev@httpd.apache.org

Hi All,

I'm having trouble with the server_rec->module_config variable and perhaps I
am misunderstanding something.

Using the apache2 C api, I have created a child_init callback (registered
through ap_hook_child_init) that is supposed to set up a per-process
resource when the server is first started (based off the pid.) Then, as each
request comes in through the handler (registered through ap_hook_handler) I
want the handler to look up that resource for its own use.

Currently I am attempting to store/retrieve this data using the
server_rec->module_config pointer. What I am having trouble with is that the
module_config pointed to during the child_init process seems to be different
than the module_config pointed to by the handler, so the resource
initialization isn't working.

Here's some a snippet code that illustrates my problem. Note that my_module
is a global variable. Am I doing something wrong?


static void get_resource(void *module_config) {
    my_config *cfg = (my_config *)ap_get_module_config(module_config,
&my_module);
    printf("module_config: %d\n", cfg);

    //...
}


static int my_child_init(apr_pool_t *p, server_rec *s) {
    printf("init server_config: %d\n", s->module_config);
    get_resource(s->module_config);
    //...
}

static int my_handler(request_rec *r){
    //...
    printf("request server_config: %d\n", r->server->module_config);
    get_resource(r->server->module_config);
    //...
}


This code prints out four different address locations where I would
expect/hope for two - one for the server_rec->module_config and one for the
returned value of ap_get_module_config().





-dave
mankyd@gmail.com

Re: WELCOME to modules-dev@httpd.apache.org

Posted by dave <ma...@gmail.com>.
On Wed, Feb 11, 2009 at 13:21, Eric Covener <co...@gmail.com> wrote:

> On Wed, Feb 11, 2009 at 1:18 PM, dave <ma...@gmail.com> wrote:
> > acfg and bcfg are the arguments to the merge calback. cfg is the result
> that
> > the merge callback returns
> > ...
> > merge_server    {acfg: 0x2b45d35e79d0    bcfg:0x2b45dc2385f0    cfg:
> > 0x2b45dc26fff0}
> > merge_dir    {acfg: 0x2b45d35e79e8    bcfg:0x2b45dc2385d8    cfg:
> > 0x2b45dc270458}
> > child_init    {pid: 2800    cfg:0x2b45d35e79d0        server:
> > 0x2b45d355f968} <-- recieving the acfg from the merge_server, not the
> return
> > value of the merge_server
> > create new
> > handler        {pid: 2800    cfg:0x2b45dc26fff0        server:
> > 0x2b45dc2361b8}  <-- recieving the return value of the merge_server
> > create new
>
> is this from passing r->server? Are you sure your request was mapped
> to a virtualhost?
>
> --
> Eric Covener
> covener@gmail.com
>


Eric, I think your question sent me down the correct line of reasoning...

Even though my request is on a virtual host, apache does not fork individual
processes for each host. Thus the child_init gets called with the main
server config, but the virtual host's server config is set before child_init
is called. Knowing this, that would explain the problem. Frustrating, but
explainable. I can hack around that assuming my explanation is correct.


-dave
mankyd@gmail.com

Re: WELCOME to modules-dev@httpd.apache.org

Posted by dave <ma...@gmail.com>.
On Wed, Feb 11, 2009 at 13:21, Eric Covener <co...@gmail.com> wrote:

> On Wed, Feb 11, 2009 at 1:18 PM, dave <ma...@gmail.com> wrote:
> > acfg and bcfg are the arguments to the merge calback. cfg is the result
> that
> > the merge callback returns
> > ...
> > merge_server    {acfg: 0x2b45d35e79d0    bcfg:0x2b45dc2385f0    cfg:
> > 0x2b45dc26fff0}
> > merge_dir    {acfg: 0x2b45d35e79e8    bcfg:0x2b45dc2385d8    cfg:
> > 0x2b45dc270458}
> > child_init    {pid: 2800    cfg:0x2b45d35e79d0        server:
> > 0x2b45d355f968} <-- recieving the acfg from the merge_server, not the
> return
> > value of the merge_server
> > create new
> > handler        {pid: 2800    cfg:0x2b45dc26fff0        server:
> > 0x2b45dc2361b8}  <-- recieving the return value of the merge_server
> > create new
>
> is this from passing r->server? Are you sure your request was mapped
> to a virtualhost?
>
> --
> Eric Covener
> covener@gmail.com
>

It's definitely setup as a virtual host.


I have this in my child_init:

static void my_child_init(apr_pool_t *p, server_rec *s) {
    printf("child_init\t{pid: %d\tcfg:%p\t\tserver: %p}\n", getpid(),
ap_get_module_config(s->module_config, &my_module), s);

    //...
}

My handler:

static int my_handler(request_rec *r) {
    //...
    printf("handler\t\t{pid: %d\tcfg:%p\t\tserver: %p}\n", getpid(),
ap_get_module_config(r->server->module_config, &my_module), r->server);
    //...
}

And my merge_server:

static void *my_merge_server_config(apr_pool_t *p, void *base, void *add) {
    my_config *cfg = (my_config *)apr_pcalloc(p, sizeof(my_config));
    //...

    printf("merge_server\t{acfg: %p\tbcfg:%p\tcfg: %p}\n", base, add, cfg);

    return (void *)cfg;
}


Here was the full output of  my debug code if its of any use:

server_config    {pid: 2800    cfg:0x2b45d35e0ac0    server: 0x2b45d3562568}
dir_config    {pid: 2800    cfg:0x2b45d35e0ad8    path: (null)}
dir_config    {pid: 2800    cfg:0x2b45dc2365c8    path: (null)}
server_config    {pid: 2800    cfg:0x2b45dc2365e0    server: 0x2b45dc2341a8}
mapper    {pid: 2800    cfg:0x2b45dc2365c8        cmd_parms: 0x7fffd77e4cd0}
merge_server    {acfg: 0x2b45d35e0ac0    bcfg:0x2b45dc2365e0    cfg:
0x2b45dc237e30}
merge_dir    {acfg: 0x2b45d35e0ad8    bcfg:0x2b45dc2365c8    cfg:
0x2b45dc238298}
server_config    {pid: 2800    cfg:0x2b45d35e79d0    server: 0x2b45d355f968}
dir_config    {pid: 2800    cfg:0x2b45d35e79e8    path: (null)}
dir_config    {pid: 2800    cfg:0x2b45dc2385d8    path: (null)}
server_config    {pid: 2800    cfg:0x2b45dc2385f0    server: 0x2b45dc2361b8}
mapper    {pid: 2800    cfg:0x2b45dc2385d8        cmd_parms: 0x7fffd77e4cd0}
merge_server    {acfg: 0x2b45d35e79d0    bcfg:0x2b45dc2385f0    cfg:
0x2b45dc26fff0}
merge_dir    {acfg: 0x2b45d35e79e8    bcfg:0x2b45dc2385d8    cfg:
0x2b45dc270458}
child_init    {pid: 2800    cfg:0x2b45d35e79d0        server:
0x2b45d355f968}
create new
handler        {pid: 2800    cfg:0x2b45dc26fff0        server:
0x2b45dc2361b8}
create new


-dave
mankyd@gmail.com

Re: WELCOME to modules-dev@httpd.apache.org

Posted by Eric Covener <co...@gmail.com>.
On Wed, Feb 11, 2009 at 1:18 PM, dave <ma...@gmail.com> wrote:
> acfg and bcfg are the arguments to the merge calback. cfg is the result that
> the merge callback returns
> ...
> merge_server    {acfg: 0x2b45d35e79d0    bcfg:0x2b45dc2385f0    cfg:
> 0x2b45dc26fff0}
> merge_dir    {acfg: 0x2b45d35e79e8    bcfg:0x2b45dc2385d8    cfg:
> 0x2b45dc270458}
> child_init    {pid: 2800    cfg:0x2b45d35e79d0        server:
> 0x2b45d355f968} <-- recieving the acfg from the merge_server, not the return
> value of the merge_server
> create new
> handler        {pid: 2800    cfg:0x2b45dc26fff0        server:
> 0x2b45dc2361b8}  <-- recieving the return value of the merge_server
> create new

is this from passing r->server? Are you sure your request was mapped
to a virtualhost?

-- 
Eric Covener
covener@gmail.com

Re: WELCOME to modules-dev@httpd.apache.org

Posted by dave <ma...@gmail.com>.
On Wed, Feb 11, 2009 at 02:16, Joe Lewis <jo...@joe-lewis.com> wrote:

>
>
> I understand - you are using both directory AND server side configs.
>  directory configs do not get created until a request.  And a merge should
> never return the same structure, meaning you should get new configs.  Even
> the directory configs don't get created until the request comes in.  In the
> handler, try setting two distinct variables, one to the server side and one
> to the directory config, and you should definitely see a difference.
>
> Well done!
> Joe
>


Well, sort of. I think I can hack it to fix the problem now, but I still
don't understand why the problem is occurring. I don't actually have any
directory configs, they're all virtuat-host-level configs (unless those
qualify as directory configs?) When I output the results of my merge, I see
the server-merge occur, followed by the child_init, but the child_init does
not receive the results of server-merge. This is simplest to show with the
end of the output:


acfg and bcfg are the arguments to the merge calback. cfg is the result that
the merge callback returns
...
merge_server    {acfg: 0x2b45d35e79d0    bcfg:0x2b45dc2385f0    cfg:
0x2b45dc26fff0}
merge_dir    {acfg: 0x2b45d35e79e8    bcfg:0x2b45dc2385d8    cfg:
0x2b45dc270458}
child_init    {pid: 2800    cfg:0x2b45d35e79d0        server:
0x2b45d355f968} <-- recieving the acfg from the merge_server, not the return
value of the merge_server
create new
handler        {pid: 2800    cfg:0x2b45dc26fff0        server:
0x2b45dc2361b8}  <-- recieving the return value of the merge_server
create new


Is this the way it is supposed to work?


-dave
mankyd@gmail.com

Re: WELCOME to modules-dev@httpd.apache.org

Posted by Joe Lewis <jo...@joe-lewis.com>.
dave wrote:
> I tried defining a merge callback for both the server level and the
> directory level, but that doesn't seem to change anything.
>
> -dave
> mankyd@gmail.com
>
>   


I understand - you are using both directory AND server side configs.  
directory configs do not get created until a request.  And a merge 
should never return the same structure, meaning you should get new 
configs.  Even the directory configs don't get created until the request 
comes in.  In the handler, try setting two distinct variables, one to 
the server side and one to the directory config, and you should 
definitely see a difference.

Well done!
Joe

Re: WELCOME to modules-dev@httpd.apache.org

Posted by dave <ma...@gmail.com>.
On Tue, Feb 10, 2009 at 19:11, Joe Lewis <jo...@joe-lewis.com> wrote:

> With your last post (the creation), it looks like you understand it well.
>  Are you only creating one process?  For example, run it with a -X parameter
> (to prevent fork()ing) so you can ensure that you aren't working across
> processes?  Printing the PID along with the %d?  Is the %d in the handler
> always the same?
>
> Joe
>

So I was in the process of creating a simple test module when I discovered
the problem had gone away (both in the test module and in the module I am
developing.) I did some more digging and discovered that it was a
configuration that is actually causing the problem. In my virtual host
definition, I have this:

#               SetHandler test
                SetHandler mymod
                MyModConfig /var/www/file

If I comment out that last line, I get a relatively simple configuration
sequence when Apache first boots (yes, this is all run with -X). cfg is the
address of the module_config variable. server/path is the address of either
the server_rec or the path variable pass into the callback.

sudo APACHE_RUN_USER=www-data APACHE_RUN_GROUP=www-data /usr/sbin/apache2 -X
server_config    {pid: 13878    cfg:0x2b7c26e32ac0    server:
0x2b7c26db4568}
dir_config    {pid: 13878    cfg:0x2b7c26e32ad8    path: (null)}
server_config    {pid: 13878    cfg:0x2b7c26e399d0    server:
0x2b7c26db1968}
dir_config    {pid: 13878    cfg:0x2b7c26e399e8    path: (null)}
child_init    {pid: 13878    cfg:0x2b7c26e399d0        server:
0x2b7c26db1968}
create new <-- this is my code creating the resources that it needs for the
process
handler        {pid: 13878    cfg:0x2b7c26e399d0        server:
0x2b7c2fa881b8} <-- notice the cfg/server addresses are the same as the line
above


When I run with the line uncommented, I get the following:

server_config    {pid: 13979    cfg:0x2b2cf82ebac0    server:
0x2b2cf826d568}
dir_config    {pid: 13979    cfg:0x2b2cf82ebad8    path: (null)}
dir_config    {pid: 13979    cfg:0x2b2d00f415c8    path: (null)}
server_config    {pid: 13979    cfg:0x2b2d00f415e0    server:
0x2b2d00f3f1a8}
mymodconfig    {pid: 13979    cfg:0x2b2d00f415c8        cmd_parms:
0x7fffb2ad90c0} <-- call to process the config
server_config    {pid: 13979    cfg:0x2b2cf82f29d0    server:
0x2b2cf826a968}
dir_config    {pid: 13979    cfg:0x2b2cf82f29e8    path: (null)}
dir_config    {pid: 13979    cfg:0x2b2d00f435d8    path: (null)}
server_config    {pid: 13979    cfg:0x2b2d00f435f0    server:
0x2b2d00f411b8}
mymodconnfig    {pid: 13979    cfg:0x2b2d00f435d8        cmd_parms:
0x7fffb2ad90c0} <-- call to process the config again
child_init    {pid: 13979    cfg:0x2b2cf82f29d0        server:
0x2b2cf826a968}
create new <-- creating the resources where it should
handler        {pid: 13979    cfg:0x2b2d00f7aff0        server:
0x2b2d00f411b8} <-- notice the cfg/server addresses are different than the
line above
create new <-- thinks the resources have not been created, so doing it again

I tried defining a merge callback for both the server level and the
directory level, but that doesn't seem to change anything.

-dave
mankyd@gmail.com

Re: WELCOME to modules-dev@httpd.apache.org

Posted by Joe Lewis <jo...@joe-lewis.com>.
dave wrote:
> Hi All,
>
> I'm having trouble with the server_rec->module_config variable and perhaps I
> am misunderstanding something.
>   

With your last post (the creation), it looks like you understand it 
well.  Are you only creating one process?  For example, run it with a -X 
parameter (to prevent fork()ing) so you can ensure that you aren't 
working across processes?  Printing the PID along with the %d?  Is the 
%d in the handler always the same?

Joe

Re: WELCOME to modules-dev@httpd.apache.org

Posted by dave <ma...@gmail.com>.
>
>
> So, how is the s->module_config being set?  I hope you are creating it in
> the per-server config create function.  Do you have that code for us to look
> at?
>
> Joe
>

I am instantiating it in the per-server callback, ala:

static void *my_create_server_config(apr_pool_t *p, server_rec *s) {
   my_config *cfg = (my_config *)apr_pcalloc(p, sizeof(my_config));
   cfg->prop1 = NULL;
   cfg->prop2 = NULL;
   //...
   return (void *)cfg;
}

For reference, one of those properties becomes the start of a linked list
that the get_resource function uses to do it's lookups.

Re: WELCOME to modules-dev@httpd.apache.org

Posted by Joe Lewis <jo...@joe-lewis.com>.
dave wrote:
> Hi All,
>
> I'm having trouble with the server_rec->module_config variable and perhaps I
> am misunderstanding something.
>
> static void get_resource(void *module_config) {
>     my_config *cfg = (my_config *)ap_get_module_config(module_config,
> &my_module);
>     printf("module_config: %d\n", cfg);
>
>     //...
> }
>
>
> static int my_child_init(apr_pool_t *p, server_rec *s) {
>     printf("init server_config: %d\n", s->module_config);
>     get_resource(s->module_config);
>     //...
> }
>
> static int my_handler(request_rec *r){
>     //...
>     printf("request server_config: %d\n", r->server->module_config);
>     get_resource(r->server->module_config);
>     //...
> }
>
>
>   

So, how is the s->module_config being set?  I hope you are creating it 
in the per-server config create function.  Do you have that code for us 
to look at?

Joe