Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#2185 closed defect (invalid)

ngx_write_chain_to_file cannot be closed file when write error

Reported by: yugo-horie@… Owned by:
Priority: minor Milestone:
Component: documentation Version: 1.19.x
Keywords: Cc:
uname -a: Linux 11143d1c63c9 4.19.76-linuxkit #1 SMP Tue May 26 11:42:35 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.19.9
built by gcc 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)
built with OpenSSL 1.1.1k 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --with-pcre-jit --with-http_ssl_module --with-file-aio --with-threads --with-openssl=/usr/local/src/openssl-1.1.1k

Description

ngx_write_chain_to_file cannot be closed file when ngx_write_file returns NGX_ERROR.
It seems to be a same issue below. I'm not sure why here is to be missing file closing.
https://github.com/nginx/nginx/pull/52/
http://hg.nginx.org/nginx/rev/4f30f75dbdf3

patch

diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c
index 1c82a8ea..7d3d5be8 100644
--- a/src/os/unix/ngx_files.c
+++ b/src/os/unix/ngx_files.c
@@ -300,9 +300,13 @@ ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset,
     /* use pwrite() if there is the only buf in a chain */

     if (cl->next == NULL) {
-        return ngx_write_file(file, cl->buf->pos,
+        n = ngx_write_file(file, cl->buf->pos,
                               (size_t) (cl->buf->last - cl->buf->pos),
                               offset);
+        if (n == NGX_ERROR) {
+            (void) ngx_close_file(file->fd);
+        }
+        return n;
     }

     total = 0;
@@ -321,6 +325,7 @@ ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset,
                                iovs[0].iov_len, offset);

             if (n == NGX_ERROR) {
+                (void) ngx_close_file(file->fd);
                 return n;
             }

@@ -330,6 +335,7 @@ ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, o
ff_t offset,
         n = ngx_writev_file(file, &vec, offset);

         if (n == NGX_ERROR) {
+            (void) ngx_close_file(file->fd);
             return n;
         }

Change History (3)

comment:1 by Maxim Dounin, 4 years ago

Resolution: invalid
Status: newclosed

Since ngx_write_chain_to_file() does not open the file, it's not its responsibility to close it.

comment:2 by yugo-horie@…, 4 years ago

Thanks comment.
In case ngx_write_chain_to_file has been called by ngx_event_pipe which returns NGX_ABORT for failing ngx_write_file(in this case, ngx_event_pipe is only called from ngx_http_upstream, all of them returns ngx_http_upstream_finalize_request(r, u, NGX_ERROR); ), I considered that it should be closed the file stream to prevent from resource leaks.
It might have another procedure which sweep and close file stream which remains opening, but I cannot find it.

Version 0, edited 4 years ago by yugo-horie@… (next)

comment:3 by Maxim Dounin, 4 years ago

All files opened during request processing are bound to the request pool, and closed automatically once the request is freed.

Note: See TracTickets for help on using tickets.