AW: svn commit: r1841225 - /httpd/httpd/trunk/modules/dav/main/props.c

2019-06-25 Thread Plüm , Rüdiger , Vodafone Group



C2 General

> -Ursprüngliche Nachricht-
> Von: Joe Orton 
> Gesendet: Dienstag, 25. Juni 2019 13:59
> An: dev@httpd.apache.org
> Betreff: Re: svn commit: r1841225 -
> /httpd/httpd/trunk/modules/dav/main/props.c
> 
> On Tue, Jun 25, 2019 at 09:06:42AM +, Plüm, Rüdiger, Vodafone Group
> wrote:
> > > On Tue, Jun 25, 2019 at 08:49:08AM +0100, Joe Orton wrote:
> > > > Unless I am missing something the apr_dir_open/apr_dir_read API
> design
> > > > is always going to have memory use proportional to directory size
> > > > because apr_dir_read() duplicates the filename into the
> directory's
> > > > pool.  We need an apr_dir_pread() or whatever which takes a pool
> > > > argument. :(
> > >
> > > OK, yes, this plus an iterpool in dav_fs_walker() fixes it.
> >
> > Only the iterpool in dav_fs_walker or plus the changes in APR
> (apr_dir_pread)?
> 
> Yes, both - PoC attached but I'm not at all confident this is safe, esp
> in the recursion case.
> 
> The test I was running before was only a "core" liveprop provided by
> mod_dav itself, so I also tested the deadprops case and that still seems
> to leak.  sbrk() to increase the heap is getting triggered by
> apr_sdbm_open() every time I saw it, but apr_dbm_open() is being pass
> the scratchpool so I think it's not the cause.

I would agree, but can you please provide the stacktrace up to sbrk?
That would ease it for me to dive in :-).

> 
> Running "dump_all_pools propdb->p" at this point gives me:
> 
>Pool 'transaction' [0x24e1d88]: 7264/8192 free (1 blocks) allocator:
> 0x24d2b90 free blocks in allocator: 0 kiB
>  Pool 'master_conn' [0x2504e28]: 1224/8192 free (1 blocks)
> allocator: 0x24d2b90 free blocks in allocator: 0 kiB
>Pool 'deferred_pool' [0x263ef18]: 8032/8192 free (1 blocks)
> allocator: 0x24d2b90 free blocks in allocator: 0 kiB
>  Pool 'request' [0x2506e38]: 13672/1646592 free (201 blocks)
> allocator: 0x24d2b90 free blocks in allocator: 0 kiB
>Pool 'mod_dav_fs-walker' [0x2524648]: 8016/8192 free (1
> blocks) allocator: 0x24d2b90 free blocks in allocator: 0 kiB
>Pool 'mod_dav-scratch' [0x2508e48]: 7224/8192 free (1 blocks)
> allocator: 0x24d2b90 free blocks in allocator: 0 kiB
>Pool 'mod_lua-vm' [0x250ce68]: 6360/16384 free (2 blocks)
> allocator: 0x24d2b90 free blocks in allocator: 0 kiB
> 
> [trimmed some whitespace only]
> 
> I think this is implicating misuse of r->pool, that's grown rather
> large?
> 

I would think so as well.

Regards

Rüdiger


Re: svn commit: r1862014 - /httpd/httpd/trunk/modules/proxy/mod_proxy_hcheck.c

2019-06-25 Thread jean-frederic clere
On 24/06/2019 21:13, Christophe JAILLET wrote:
> Le 24/06/2019 à 18:29, jfcl...@apache.org a écrit :
>> Author: jfclere
>> Date: Mon Jun 24 16:29:22 2019
>> New Revision: 1862014
>>
>> URL: http://svn.apache.org/viewvc?rev=1862014=rev
>> Log:
>> Set connectiontimeout for mod_proxy_hcheck.
>> Fix for https://issues.jboss.org/browse/JBCS-448
>>
>> Modified:
>>  httpd/httpd/trunk/modules/proxy/mod_proxy_hcheck.c
>>
>> Modified: httpd/httpd/trunk/modules/proxy/mod_proxy_hcheck.c
>> URL:
>> http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/mod_proxy_hcheck.c?rev=1862014=1862013=1862014=diff
>>
>> ==
>>
>> --- httpd/httpd/trunk/modules/proxy/mod_proxy_hcheck.c (original)
>> +++ httpd/httpd/trunk/modules/proxy/mod_proxy_hcheck.c Mon Jun 24
>> 16:29:22 2019
>> @@ -487,6 +487,10 @@ static proxy_worker *hc_get_hcworker(sct
>>   hc->hash.def = hc->s->hash.def =
>> ap_proxy_hashfunc(hc->s->name, PROXY_HASHFUNC_DEFAULT);
>>   hc->hash.fnv = hc->s->hash.fnv =
>> ap_proxy_hashfunc(hc->s->name, PROXY_HASHFUNC_FNV);
>>   hc->s->port = port;
>> +    if (worker->s->conn_timeout_set) {
>> +    hc->s->conn_timeout_set = worker->s->conn_timeout_set;
>> +    hc->s->conn_timeout = worker->s->conn_timeout;
>> +    }
>>   /* Do not disable worker in case of errors */
>>   hc->s->status |= PROXY_WORKER_IGNORE_ERRORS;
>>   /* Mark as the "generic" worker */
> 
> 
> Hi, a similar approach is available in
> https://bz.apache.org/bugzilla/show_bug.cgi?id=60948.
> 
> This BZ also extends templates and makes this new connection time-out
> configurable.
> 
> CJ
> 
> 
> 
> 

Thanks I missed it... Now trying to understand why we need 2 connection
timeouts? We are checking the connection to the backend , the backend
should behave the same way for connection... Did I miss something?


-- 
Cheers

Jean-Frederic


Re: svn commit: r1841225 - /httpd/httpd/trunk/modules/dav/main/props.c

2019-06-25 Thread Joe Orton
On Tue, Jun 25, 2019 at 09:06:42AM +, Plüm, Rüdiger, Vodafone Group wrote:
> > On Tue, Jun 25, 2019 at 08:49:08AM +0100, Joe Orton wrote:
> > > Unless I am missing something the apr_dir_open/apr_dir_read API design
> > > is always going to have memory use proportional to directory size
> > > because apr_dir_read() duplicates the filename into the directory's
> > > pool.  We need an apr_dir_pread() or whatever which takes a pool
> > > argument. :(
> > 
> > OK, yes, this plus an iterpool in dav_fs_walker() fixes it.
> 
> Only the iterpool in dav_fs_walker or plus the changes in APR (apr_dir_pread)?

Yes, both - PoC attached but I'm not at all confident this is safe, esp 
in the recursion case.

The test I was running before was only a "core" liveprop provided by 
mod_dav itself, so I also tested the deadprops case and that still seems 
to leak.  sbrk() to increase the heap is getting triggered by 
apr_sdbm_open() every time I saw it, but apr_dbm_open() is being pass 
the scratchpool so I think it's not the cause.

Running "dump_all_pools propdb->p" at this point gives me:

   Pool 'transaction' [0x24e1d88]: 7264/8192 free (1 blocks) allocator: 
0x24d2b90 free blocks in allocator: 0 kiB
 Pool 'master_conn' [0x2504e28]: 1224/8192 free (1 blocks) allocator: 
0x24d2b90 free blocks in allocator: 0 kiB
   Pool 'deferred_pool' [0x263ef18]: 8032/8192 free (1 blocks) allocator: 
0x24d2b90 free blocks in allocator: 0 kiB
 Pool 'request' [0x2506e38]: 13672/1646592 free (201 blocks) allocator: 
0x24d2b90 free blocks in allocator: 0 kiB
   Pool 'mod_dav_fs-walker' [0x2524648]: 8016/8192 free (1 blocks) 
allocator: 0x24d2b90 free blocks in allocator: 0 kiB
   Pool 'mod_dav-scratch' [0x2508e48]: 7224/8192 free (1 blocks) 
allocator: 0x24d2b90 free blocks in allocator: 0 kiB
   Pool 'mod_lua-vm' [0x250ce68]: 6360/16384 free (2 blocks) allocator: 
0x24d2b90 free blocks in allocator: 0 kiB

[trimmed some whitespace only]

I think this is implicating misuse of r->pool, that's grown rather 
large?

Regards, Joe

Index: include/apr_file_info.h
===
--- include/apr_file_info.h (revision 1862036)
+++ include/apr_file_info.h (working copy)
@@ -268,6 +268,24 @@
apr_dir_t *thedir);
 
 /**
+ * Read the next entry from the specified directory. 
+ * @param finfo the file info structure and filled in by apr_dir_read
+ * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_
+ values 
+ * @param thedir the directory descriptor returned from apr_dir_open
+ * @param pool the pool to use for allocations
+ * @remark No ordering is guaranteed for the entries read.
+ *
+ * @note If @c APR_INCOMPLETE is returned all the fields in @a finfo may
+ *   not be filled in, and you need to check the @c finfo->valid bitmask
+ *   to verify that what you're looking for is there. When no more
+ *   entries are available, APR_ENOENT is returned.
+ */
+APR_DECLARE(apr_status_t) apr_dir_pread(apr_finfo_t *finfo, apr_int32_t wanted,
+apr_dir_t *thedir, apr_pool_t *pool);
+
+
+/**
  * Rewind the directory to the first entry.
  * @param thedir the directory descriptor to rewind.
  */
Index: file_io/unix/dir.c
===
--- file_io/unix/dir.c  (revision 1862036)
+++ file_io/unix/dir.c  (working copy)
@@ -133,6 +133,12 @@
 apr_status_t apr_dir_read(apr_finfo_t *finfo, apr_int32_t wanted,
   apr_dir_t *thedir)
 {
+return apr_dir_pread(finfo, wanted, thedir, thedir->pool);
+}
+
+apr_status_t apr_dir_pread(apr_finfo_t *finfo, apr_int32_t wanted,
+   apr_dir_t *thedir, apr_pool_t *pool)
+{
 apr_status_t ret = 0;
 #ifdef DIRENT_TYPE
 apr_filetype_e type;
@@ -242,7 +248,7 @@
 apr_cpystrn(end, thedir->entry->d_name, 
 sizeof fspec - (end - fspec));
 
-ret = apr_stat(finfo, fspec, APR_FINFO_LINK | wanted, thedir->pool);
+ret = apr_stat(finfo, fspec, APR_FINFO_LINK | wanted, pool);
 /* We passed a stack name that will disappear */
 finfo->fname = NULL;
 }
@@ -254,7 +260,7 @@
 /* We don't bail because we fail to stat, when we are only -required-
  * to readdir... but the result will be APR_INCOMPLETE
  */
-finfo->pool = thedir->pool;
+finfo->pool = pool;
 finfo->valid = 0;
 #ifdef DIRENT_TYPE
 if (type != APR_UNKFILE) {
@@ -270,7 +276,7 @@
 #endif
 }
 
-finfo->name = apr_pstrdup(thedir->pool, thedir->entry->d_name);
+finfo->name = apr_pstrdup(pool, thedir->entry->d_name);
 finfo->valid |= APR_FINFO_NAME;
 
 if (wanted)
Index: modules/dav/fs/repos.c
===
--- 

AW: svn commit: r1841225 - /httpd/httpd/trunk/modules/dav/main/props.c

2019-06-25 Thread Plüm , Rüdiger , Vodafone Group



C2 General

> -Ursprüngliche Nachricht-
> Von: Joe Orton 
> Gesendet: Dienstag, 25. Juni 2019 10:45
> An: dev@httpd.apache.org
> Betreff: Re: svn commit: r1841225 -
> /httpd/httpd/trunk/modules/dav/main/props.c
> 
> On Tue, Jun 25, 2019 at 08:49:08AM +0100, Joe Orton wrote:
> > Unless I am missing something the apr_dir_open/apr_dir_read API design
> > is always going to have memory use proportional to directory size
> > because apr_dir_read() duplicates the filename into the directory's
> > pool.  We need an apr_dir_pread() or whatever which takes a pool
> > argument. :(
> 
> OK, yes, this plus an iterpool in dav_fs_walker() fixes it.

Only the iterpool in dav_fs_walker or plus the changes in APR (apr_dir_pread)?

> 
> I've been using the python "psrecord" (from pip) to check this rather
> than my traditional method of "eyeballing top", here are the charts for
> running 10x a PROPFIND with ~100K files, for

Great plots. Thanks for pointing to the tool.

> 
> a) trunk - steep gradient, ~20mb consumed
> b) trunk plus the patch from my previous post, ~5mb?
> c) (b) plus iterpool in dav_fs_walker - flat
> 
> so I think (b) is fine to commit but with the recursion in dav_fs_walker
> I am not at all sure this stuff is safe yet, will need some more
> testing.

The recursion stuff could be tricky. Probably a separate (sub-)pool for 
apr_dir_open
on each recursion level and separate iterpools on each recursion level?

Regards

Rüdiger


cmake help wanted

2019-06-25 Thread Stefan Eissing
I added the cmake definitions for mod_md in r1862041. If someone could find the 
time to run this on Windows in the coming weeks, that'd be great.

- Stefan

Re: svn commit: r1841225 - /httpd/httpd/trunk/modules/dav/main/props.c

2019-06-25 Thread Stefan Eissing
Nice work!

> Am 25.06.2019 um 10:44 schrieb Joe Orton :
> 
> 



Re: svn commit: r1841225 - /httpd/httpd/trunk/modules/dav/main/props.c

2019-06-25 Thread Joe Orton
On Tue, Jun 25, 2019 at 08:49:08AM +0100, Joe Orton wrote:
> Unless I am missing something the apr_dir_open/apr_dir_read API design 
> is always going to have memory use proportional to directory size 
> because apr_dir_read() duplicates the filename into the directory's 
> pool.  We need an apr_dir_pread() or whatever which takes a pool 
> argument. :(

OK, yes, this plus an iterpool in dav_fs_walker() fixes it.  

I've been using the python "psrecord" (from pip) to check this rather 
than my traditional method of "eyeballing top", here are the charts for 
running 10x a PROPFIND with ~100K files, for 

a) trunk - steep gradient, ~20mb consumed
b) trunk plus the patch from my previous post, ~5mb?
c) (b) plus iterpool in dav_fs_walker - flat

so I think (b) is fine to commit but with the recursion in dav_fs_walker 
I am not at all sure this stuff is safe yet, will need some more 
testing.


AW: svn commit: r1841225 - /httpd/httpd/trunk/modules/dav/main/props.c

2019-06-25 Thread Plüm , Rüdiger , Vodafone Group



C2 General

> -Ursprüngliche Nachricht-
> Von: Joe Orton 
> Gesendet: Dienstag, 25. Juni 2019 09:49
> An: dev@httpd.apache.org
> Betreff: Re: svn commit: r1841225 -
> /httpd/httpd/trunk/modules/dav/main/props.c
> 
> On Mon, Jun 24, 2019 at 09:54:21PM +0200, Ruediger Pluem wrote:
> > On 06/24/2019 07:04 PM, Joe Orton wrote:
> > > #11 0x7f8110ce6448 in dav_do_prop_subreq (propdb=0x100cfc0) at
> props.c:331
> >
> > What if you go here and do a
> >
> > dump_all_pools propdb->p
> >
> > and do it again when you hit the next sbrk and the next one and so on?
> Something suspicious?
> 
> Well I did this and immediately noticed something suspicious on the
> previous line, e_uri is allocated from resource->pool (=r->pool) rather
> than propbb->p, so, yet again the precision accuracy of your insights is

Very good catch. Great that you found it.

> beyond belief Ruediger :) :)
> 
> This fixed a significant leak, but r->pool is still growing.  I think
> the remaining problem is use of r->pool in dav_fs_walker, i.e. is
> mod_dav_fs specific.

Do you think it is now good enough to commit at least as a first step?

> 
> Unless I am missing something the apr_dir_open/apr_dir_read API design
> is always going to have memory use proportional to directory size
> because apr_dir_read() duplicates the filename into the directory's
> pool.  We need an apr_dir_pread() or whatever which takes a pool
> argument. :(

In order to fix this leak, I agree that we would need this.
The pool is also used for apr_stat inside apr_dir_read, but I fail to see
how it consumes memory.

Another related question: Do you think it would be beneficial if we replace
the apr_psprintf with apr_pstrcat in props.c as long as they only concat 
strings without
further formatting?


Regards

Rüdiger


Re: svn commit: r1841225 - /httpd/httpd/trunk/modules/dav/main/props.c

2019-06-25 Thread Joe Orton
On Mon, Jun 24, 2019 at 09:54:21PM +0200, Ruediger Pluem wrote:
> On 06/24/2019 07:04 PM, Joe Orton wrote:
> > #11 0x7f8110ce6448 in dav_do_prop_subreq (propdb=0x100cfc0) at 
> > props.c:331
> 
> What if you go here and do a
> 
> dump_all_pools propdb->p
> 
> and do it again when you hit the next sbrk and the next one and so on? 
> Something suspicious?

Well I did this and immediately noticed something suspicious on the 
previous line, e_uri is allocated from resource->pool (=r->pool) rather 
than propbb->p, so, yet again the precision accuracy of your insights is 
beyond belief Ruediger :) :)

This fixed a significant leak, but r->pool is still growing.  I think 
the remaining problem is use of r->pool in dav_fs_walker, i.e. is 
mod_dav_fs specific.

Unless I am missing something the apr_dir_open/apr_dir_read API design 
is always going to have memory use proportional to directory size 
because apr_dir_read() duplicates the filename into the directory's 
pool.  We need an apr_dir_pread() or whatever which takes a pool 
argument. :(

Index: modules/dav/main/mod_dav.c
===
--- modules/dav/main/mod_dav.c  (revision 1861995)
+++ modules/dav/main/mod_dav.c  (working copy)
@@ -563,6 +563,7 @@
 dav_begin_multistatus(bb, r, status, namespaces);
 
 apr_pool_create(, r->pool);
+apr_pool_tag(subpool, "mod_dav-multistatus");
 
 for (; first != NULL; first = first->next) {
   apr_pool_clear(subpool);
@@ -2027,8 +2028,9 @@
 ** Note: we cast to lose the "const". The propdb won't try to change
 ** the resource, however, since we are opening readonly.
 */
-err = dav_open_propdb(ctx->r, ctx->w.lockdb, wres->resource, 1,
-  ctx->doc ? ctx->doc->namespaces : NULL, );
+err = dav_popen_propdb(ctx->scratchpool,
+   ctx->r, ctx->w.lockdb, wres->resource, 1,
+   ctx->doc ? ctx->doc->namespaces : NULL, );
 if (err != NULL) {
 /* ### do something with err! */
 
Index: modules/dav/main/mod_dav.h
===
--- modules/dav/main/mod_dav.h  (revision 1861995)
+++ modules/dav/main/mod_dav.h  (working copy)
@@ -1596,6 +1596,16 @@
 apr_array_header_t *ns_xlate,
 dav_propdb **propdb);
 
+DAV_DECLARE(dav_error *) dav_popen_propdb(
+apr_pool_t *p,
+request_rec *r,
+dav_lockdb *lockdb,
+const dav_resource *resource,
+int ro,
+apr_array_header_t *ns_xlate,
+dav_propdb **propdb);
+
+
 DAV_DECLARE(void) dav_close_propdb(dav_propdb *db);
 
 DAV_DECLARE(dav_get_props_result) dav_get_props(
Index: modules/dav/main/props.c
===
--- modules/dav/main/props.c(revision 1861995)
+++ modules/dav/main/props.c(working copy)
@@ -323,7 +323,7 @@
 {
 /* need to escape the uri that's in the resource struct because during
  * the property walker it's not encoded. */
-const char *e_uri = ap_escape_uri(propdb->resource->pool,
+const char *e_uri = ap_escape_uri(propdb->p,
   propdb->resource->uri);
 
 /* perform a "GET" on the resource's URI (note that the resource
@@ -524,22 +524,21 @@
 apr_array_header_t * ns_xlate,
 dav_propdb **p_propdb)
 {
+return dav_popen_propdb(r->pool, r, lockdb, resource, ro, ns_xlate, 
p_propdb);
+}
+
+DAV_DECLARE(dav_error *)dav_popen_propdb(apr_pool_t *p,
+ request_rec *r, dav_lockdb *lockdb,
+ const dav_resource *resource,
+ int ro,
+ apr_array_header_t * ns_xlate,
+ dav_propdb **p_propdb)
+{
 dav_propdb *propdb = NULL;
-/*
- * Check if we have tucked away a previous propdb and reuse it.
- * Otherwise create a new one and tuck it away
- */
-apr_pool_userdata_get((void **), "propdb", r->pool);
-if (!propdb) {
-propdb = apr_pcalloc(r->pool, sizeof(*propdb));
-apr_pool_userdata_setn(propdb, "propdb", NULL, r->pool);
-apr_pool_create(>p, r->pool);
-}
-else {
-/* Play safe and clear the pool of the reused probdb */
-apr_pool_clear(propdb->p);
-}
 
+propdb = apr_pcalloc(p, sizeof(*propdb));
+propdb->p = p;
+
 *p_propdb = NULL;
 
 #if DAV_DEBUG
@@ -579,8 +578,6 @@
 ap_destroy_sub_req(propdb->subreq);
 propdb->subreq = NULL;
 }
-
-apr_pool_clear(propdb->p);
 }
 
 DAV_DECLARE(dav_get_props_result) dav_get_allprops(dav_propdb *propdb,