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