Strange behavior with custom module and http proxy

Brian Bruns brian at bruns.com
Tue Dec 22 19:54:06 MSK 2009


Hi Piotr,

That makes perfect sense now that I think about it.  The patch worked perfectly.

Thank you for all your help!

Brian

2009/12/22 Piotr Sikora <piotr.sikora at frickle.com>:
> Hi Brian,
>
>> I have created a (very) small module that demonstrates the problem.
>> It can be downloaded here:
>>
>> http://www.mediafire.com/?yij1tmyjzyz
>
> Few notes:
> 1) This problem isn't related to caching at all, simple "proxy_pass" also
> produces this behavior.
> 2) I believe that execv() is source of this problem, not fork().
>
> Anyway, it seems that calling execv() with open sockets copies all file
> descriptors to new process and nginx is expecting some action to happen on
> them. Since there is no action, nginx waits until your process exits (and OS
> closes all its file descriptors for you).
>
> I've attached simple patch, which fixes this problem.
>
> There are few things to consider:
> 1) This works well with kevent (*BSD), I'm not sure what will be the effect
> of closing sockets registered with epoll (Linux), because when I was
> developing ngx_slowfs_cache, nginx crashed when listening sockets were
> closed after fork() under Linux.
> 2) This works as expected for single request. Under high load you might need
> to close sockets for *all* requests... But I'm not really sure about this
> and it's up to you to test this.
>
> Best regards,
> Piotr Sikora < piotr.sikora at frickle.com >
>
>
> --- ngx_http_bogus_module.c.orig        Tue Dec 22 14:18:43 2009
> +++ ngx_http_bogus_module.c     Tue Dec 22 14:18:21 2009
> @@ -10,7 +10,7 @@
>
>  static char *ngx_http_bogus_set(ngx_conf_t *cf, ngx_command_t *cmd, void
> *conf);
>  static void *ngx_http_bogus_create_loc_conf(ngx_conf_t *cf);
> -void ngx_http_bogus_launch_child();
> +void ngx_http_bogus_launch_child(ngx_http_request_t *r);
>
>  static ngx_command_t  ngx_http_bogus_commands[] = {
>
> @@ -56,7 +56,7 @@
>  };
>
>  void
> -ngx_http_bogus_launch_child()
> +ngx_http_bogus_launch_child(ngx_http_request_t *r)
>  {
>    char *argv[] = {"bogochild", NULL};
>    pid_t child = 0;
> @@ -67,6 +67,7 @@
>    if (stat(child_path, &statbuf)==-1) return;
>
>    if ((child = fork())==0) {
> +        ngx_close_connection(r->connection);
>         execv(child_path, argv);
>    } else {
>      /* wait for child to be ready, signaled by dead parent */
> @@ -90,7 +91,7 @@
>     log = r->connection->log;
>     ngx_log_error(NGX_LOG_INFO, log, 0, "entering
> bogus_request_body_handler");
>
> -    ngx_http_bogus_launch_child();
> +    ngx_http_bogus_launch_child(r);
>     output = (u_char *) strdup("Success");
>     len = ngx_strlen(output);
>     b = ngx_create_temp_buf(r->pool, len + 1);
>
> _______________________________________________
> nginx mailing list
> nginx at nginx.org
> http://nginx.org/mailman/listinfo/nginx
>
>



More information about the nginx mailing list