Merge ~mirespace/ubuntu/+source/augeas:lp-1828074-bionic-augeas-memorybomb into ubuntu/+source/augeas:ubuntu/bionic-devel

Proposed by Miriam España Acebal
Status: Approved
Approved by: Utkarsh Gupta
Approved revision: b0c6fa20dcc275383ba7dcc3d0ac88ad40aabc38
Proposed branch: ~mirespace/ubuntu/+source/augeas:lp-1828074-bionic-augeas-memorybomb
Merge into: ubuntu/+source/augeas:ubuntu/bionic-devel
Diff against target: 206 lines (+162/-1)
5 files modified
debian/changelog (+13/-0)
debian/control (+2/-1)
debian/patches/0005-Replace-pure-funcs-calls-in-path-expr-w-result.patch (+143/-0)
debian/patches/series (+1/-0)
debian/rules (+3/-0)
Reviewer Review Type Date Requested Status
Utkarsh Gupta (community) Approve
Canonical Server MOTU reviewers Pending
Review via email: mp+408941@code.launchpad.net

Description of the change

Hi Team,

PPA for these SRUs is : ppa:mirespace/sru-lp-1828074-bionic-augeas-large-http-files

Two issues were fixed here:

- The use of memory grows as a site conf file enlarges when using augeas:
    * d/p/0005-Memory-usage-issues-with-large-Apache-httpd-configuration-files.patch:
      Replace pure function invocations in
      path expressions with their result. Thanks to
      David Lutterkort <email address hidden>
      (LP: #1828074).

    Steps to reproduce the issue are described in the SRU template of the bug.

- Package augeas was FTBFS in Bionic:
    * d/rules: Disable gnulib tests, thanks to Matthias
    Klose <email address hidden>
    (Closes: #919662)(LP: #1813566).

  Without this, the package can't be built on Bionic (2 tests fail: test-rwlock1 , test-thread_create). This tests are not checking augeas itself as commented on https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=919662

Both fixes have been cherry picked from upstream (the patch) and Debian.

Built tests passed ok (No DEP8 tests present):

============================================================================
Testsuite summary for augeas 1.10.1
============================================================================
# TOTAL: 247
# PASS: 243
# SKIP: 4
# XFAIL: 0
# FAIL: 0
# XPASS: 0
# ERROR: 0
============================================================================

Thanks in advance!

To post a comment you must log in.
Revision history for this message
Utkarsh Gupta (utkarsh) wrote :

Hello,

Thank you for the MP, please find the comments inline. TIA! \o/

review: Needs Fixing
Revision history for this message
Miriam España Acebal (mirespace) wrote :

Hello... some changes are done, some answers are inline with the no-changes.

Let me what you think and thanks for reviewing.

Revision history for this message
Miriam España Acebal (mirespace) wrote :

(For the inline comments)

Revision history for this message
Utkarsh Gupta (utkarsh) wrote :

Looks good, thanks, Miriam. I'll make minor edits in the d/ch entry and the patch whilst sponsoring.

review: Approve
Revision history for this message
Miriam España Acebal (mirespace) wrote :

SRUs templates updated!

Revision history for this message
Utkarsh Gupta (utkarsh) wrote :

$ dput ubuntu ../augeas_1.10.1-2ubuntu1_source.changes
Checking signature on .changes
gpg: ../augeas_1.10.1-2ubuntu1_source.changes: Valid signature from 823E967606C34B96
Checking signature on .dsc
gpg: ../augeas_1.10.1-2ubuntu1.dsc: Valid signature from 823E967606C34B96
Package includes an .orig.tar.gz file although the debian revision suggests
that it might not be required. Multiple uploads of the .orig.tar.gz may be
rejected by the upload queue management software.
Uploading to ubuntu (via ftp to upload.ubuntu.com):
  Uploading augeas_1.10.1-2ubuntu1.dsc: done.
  Uploading augeas_1.10.1.orig.tar.gz: done.
  Uploading augeas_1.10.1-2ubuntu1.debian.tar.xz: done.
  Uploading augeas_1.10.1-2ubuntu1_source.buildinfo: done.
  Uploading augeas_1.10.1-2ubuntu1_source.changes: done.
Successfully uploaded packages.

Unmerged commits

b0c6fa2... by Miriam España Acebal

changelog: 1.10.1-2ubuntu1

1e324e6... by Miriam España Acebal

update-maintainers

f4e6a83... by Miriam España Acebal

* d/rules: Disable gnulib tests due to that tests are not testing augeas
  itself. Thanks to Matthias Klose (Closes: #919662)(LP: #1813566).

c243422... by Miriam España Acebal

  * d/p/0005-Replace-pure-funcs-calls-in-path-expr-w-result.patch:
    Replace pure function invocations in path
    expressions with their result. Thanks to
    David Lutterkort <email address hidden>.
    (LP: #1828074)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index a3fef72..7690cfa 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,16 @@
6+augeas (1.10.1-2ubuntu1) bionic; urgency=medium
7+
8+ * d/p/0005-Replace-pure-funcs-calls-in-path-expr-w-result.patch:
9+ Replace pure function invocations in path
10+ expressions with their result. Thanks to
11+ David Lutterkort <github@watzmann.net>.
12+ (LP: #1828074)
13+ * d/rules: Disable gnulib tests due to that tests are not
14+ testing augeas itself. Thanks to Matthias Klose
15+ (Closes: #919662)(LP: #1813566).
16+
17+ -- Miriam España Acebal <miriam.espana@canonical.com> Mon, 20 Sep 2021 11:18:53 +0200
18+
19 augeas (1.10.1-2) unstable; urgency=medium
20
21 * Add correct file paths to clamav.aug (Closes: #892913)
22diff --git a/debian/control b/debian/control
23index 523f25d..20711d5 100644
24--- a/debian/control
25+++ b/debian/control
26@@ -1,6 +1,7 @@
27 Source: augeas
28 Priority: optional
29-Maintainer: Hilko Bengen <bengen@debian.org>
30+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
31+XSBC-Original-Maintainer: Hilko Bengen <bengen@debian.org>
32 Uploaders: Micah Anderson <micah@debian.org>
33 Build-Depends: debhelper (>= 10~),
34 libreadline-dev,
35diff --git a/debian/patches/0005-Replace-pure-funcs-calls-in-path-expr-w-result.patch b/debian/patches/0005-Replace-pure-funcs-calls-in-path-expr-w-result.patch
36new file mode 100644
37index 0000000..57513cd
38--- /dev/null
39+++ b/debian/patches/0005-Replace-pure-funcs-calls-in-path-expr-w-result.patch
40@@ -0,0 +1,143 @@
41+Description: Replace pure function invocations in path expressions with their result
42+ .
43+ In path expressions, we generally need to evaluate functions against every
44+ node that we consider for the result set. For example, in the path
45+ expression /files/etc/hosts/*[ipaddr =~ regexp('127\\.')], the regexp
46+ function was evaluated against every entry in /etc/hosts. Evaluating that
47+ function requires the construction and compilation of a new regexp. Because
48+ of how memory is managed during evaluation of path expressions, the memory
49+ used by all these copies of the same regexp is only freed after we are done
50+ evaluating the path expression. This causes unacceptable memory usage in
51+ large files (see https://github.com/hercules-team/augeas/issues/569)
52+ .
53+ To avoid these issues, we now distinguish between pure and impure functions
54+ in the path expression interpreter. When we encounter a pure function, we
55+ change the AST for the path expression so that the function invocation is
56+ replaced with the result of invoking the function. With the example above,
57+ that means we only construct and compile the regexp '127\\.' once,
58+ regardless of how many nodes it gets checked against. That leads to a
59+ dramatic reduction in the memory required to evaluate path expressions with
60+ such constructs against large files.
61+Author: David Lutterkort <github@watzmann.net>
62+Origin: upstream
63+Bug: https://github.com/hercules-team/augeas/issues/569
64+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/augeas/+bug/1828074
65+Forwarded: not-needed
66+Applied-Upstream: https://github.com/hercules-team/augeas/pull/578/commits/bbf31f719db54916993be9042254f6d77b61cb13
67+Last-Update: 2021-09-20
68+---
69+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
70+diff --git a/src/pathx.c b/src/pathx.c
71+index 48c8b0b1..4c2aa3a7 100644
72+--- a/src/pathx.c
73++++ b/src/pathx.c
74+@@ -208,6 +208,10 @@ struct expr {
75+ struct { /* E_APP */
76+ const struct func *func;
77+ struct expr **args;
78++ /* If fold is true, replace this function invocation
79++ * with its value after the first time we evaluate this
80++ * expression */
81++ bool fold;
82+ };
83+ };
84+ };
85+@@ -282,6 +286,7 @@ struct func {
86+ const char *name;
87+ unsigned int arity;
88+ enum type type;
89++ bool pure; /* Result only depends on args */
90+ const enum type *arg_types;
91+ func_impl_t impl;
92+ };
93+@@ -304,40 +309,40 @@ static const enum type arg_types_nodeset_string[] = { T_NODESET, T_STRING };
94+
95+ static const struct func builtin_funcs[] = {
96+ { .name = "last", .arity = 0, .type = T_NUMBER, .arg_types = NULL,
97+- .impl = func_last },
98++ .impl = func_last, .pure = false },
99+ { .name = "position", .arity = 0, .type = T_NUMBER, .arg_types = NULL,
100+- .impl = func_position },
101++ .impl = func_position, .pure = false },
102+ { .name = "label", .arity = 0, .type = T_STRING, .arg_types = NULL,
103+- .impl = func_label },
104++ .impl = func_label, .pure = false },
105+ { .name = "count", .arity = 1, .type = T_NUMBER,
106+ .arg_types = arg_types_nodeset,
107+- .impl = func_count },
108++ .impl = func_count, .pure = false },
109+ { .name = "regexp", .arity = 1, .type = T_REGEXP,
110+ .arg_types = arg_types_string,
111+- .impl = func_regexp },
112++ .impl = func_regexp, .pure = true },
113+ { .name = "regexp", .arity = 1, .type = T_REGEXP,
114+ .arg_types = arg_types_nodeset,
115+- .impl = func_regexp },
116++ .impl = func_regexp, .pure = true },
117+ { .name = "regexp", .arity = 2, .type = T_REGEXP,
118+ .arg_types = arg_types_string_string,
119+- .impl = func_regexp_flag },
120++ .impl = func_regexp_flag, .pure = true },
121+ { .name = "regexp", .arity = 2, .type = T_REGEXP,
122+ .arg_types = arg_types_nodeset_string,
123+- .impl = func_regexp_flag },
124++ .impl = func_regexp_flag, .pure = true },
125+ { .name = "glob", .arity = 1, .type = T_REGEXP,
126+ .arg_types = arg_types_string,
127+- .impl = func_glob },
128++ .impl = func_glob, .pure = true },
129+ { .name = "glob", .arity = 1, .type = T_REGEXP,
130+ .arg_types = arg_types_nodeset,
131+- .impl = func_glob },
132++ .impl = func_glob, .pure = true },
133+ { .name = "int", .arity = 1, .type = T_NUMBER,
134+- .arg_types = arg_types_string, .impl = func_int },
135++ .arg_types = arg_types_string, .impl = func_int, .pure = false },
136+ { .name = "int", .arity = 1, .type = T_NUMBER,
137+- .arg_types = arg_types_nodeset, .impl = func_int },
138++ .arg_types = arg_types_nodeset, .impl = func_int, .pure = false },
139+ { .name = "int", .arity = 1, .type = T_NUMBER,
140+- .arg_types = arg_types_bool, .impl = func_int },
141++ .arg_types = arg_types_bool, .impl = func_int, .pure = false },
142+ { .name = "not", .arity = 1, .type = T_BOOLEAN,
143+- .arg_types = arg_types_bool, .impl = func_not }
144++ .arg_types = arg_types_bool, .impl = func_not, .pure = true }
145+ };
146+
147+ #define RET_ON_ERROR \
148+@@ -1409,6 +1414,16 @@ static void eval_expr(struct expr *expr, struct state *state) {
149+ break;
150+ case E_APP:
151+ eval_app(expr, state);
152++ if (expr->fold) {
153++ /* Do constant folding: replace the function application with
154++ * a reference to the value that resulted from evaluating it */
155++ for (int i=0; i < expr->func->arity; i++)
156++ free_expr(expr->args[i]);
157++ free(expr->args);
158++ value_ind_t vind = state->values_used - 1;
159++ expr->tag = E_VALUE;
160++ expr->value_ind = state->values[vind];
161++ }
162+ break;
163+ default:
164+ assert(0);
165+@@ -1493,6 +1508,18 @@ static void check_app(struct expr *expr, struct state *state) {
166+ if (f < ARRAY_CARDINALITY(builtin_funcs)) {
167+ expr->func = builtin_funcs + f;
168+ expr->type = expr->func->type;
169++ expr->fold = expr->func->pure;
170++ if (expr->fold) {
171++ /* We only do constant folding for invocations of pure functions
172++ * whose arguments are literal values. That misses opportunities
173++ * for constant folding, e.g., "regexp('foo' + 'bar')" but is
174++ * a bit simpler than doing full tracking of constants
175++ */
176++ for (int i=0; i < expr->func->arity; i++) {
177++ if (expr->args[i]->tag != E_VALUE)
178++ expr->fold = false;
179++ }
180++ }
181+ } else {
182+ STATE_ERROR(state, PATHX_ETYPE);
183+ }
184diff --git a/debian/patches/series b/debian/patches/series
185index 03f97f2..c9d719e 100644
186--- a/debian/patches/series
187+++ b/debian/patches/series
188@@ -2,3 +2,4 @@
189 0002-Skip-tests-that-need-root-privileges-when-fakeroot-h.patch
190 0003-Make-NRPE-lens-less-strict.patch
191 0004-Add-Debian-specific-paths-for-ClamAV-configuration-f.patch
192+0005-Replace-pure-funcs-calls-in-path-expr-w-result.patch
193diff --git a/debian/rules b/debian/rules
194index f077249..524d61e 100755
195--- a/debian/rules
196+++ b/debian/rules
197@@ -10,6 +10,9 @@ include /usr/share/dpkg/buildflags.mk
198 override_dh_autoreconf:
199 dh_autoreconf autoreconf -- -i
200
201+override_dh_auto_configure:
202+ dh_auto_configure -- --disable-gnulib-tests
203+
204 override_dh_auto_build:
205 rm -f tetsts/lens-*.sh
206 dh_auto_build

Subscribers

People subscribed via source and target branches