Skip to content

Commit 680e160

Browse files
authored
Merge pull request #5742 from btriller/CFE-4511
Support process_select bodies without process_result attribute
2 parents de36237 + 0937a21 commit 680e160

File tree

4 files changed

+151
-67
lines changed

4 files changed

+151
-67
lines changed

cf-agent/verify_processes.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,6 @@ static bool ProcessSanityChecks(const Attributes *a, const Promise *pp)
9393
ret = false;
9494
}
9595

96-
if ((a->haveselect) && (!a->process_select.process_result))
97-
{
98-
Log(LOG_LEVEL_ERR, "Process select constraint body promised no result (check body definition)");
99-
PromiseRef(LOG_LEVEL_ERR, pp);
100-
ret = false;
101-
}
102-
10396
// CF_NOINT is the value assigned when match_range is not specified
10497
if ((a->haveprocess_count) && ((a->process_count.min_range == CF_NOINT) || (a->process_count.max_range == CF_NOINT)))
10598
{
@@ -115,7 +108,6 @@ static bool ProcessSanityChecks(const Attributes *a, const Promise *pp)
115108
ret = false;
116109
}
117110

118-
119111
return ret;
120112
}
121113

libpromises/attributes.c

Lines changed: 1 addition & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,15 +1317,9 @@ ProcessSelect GetProcessFilterConstraints(const EvalContext *ctx, const Promise
13171317
{
13181318
ProcessSelect p;
13191319
char *value;
1320-
int entries = 0;
13211320

13221321
// get constraint process ID
13231322
value = PromiseGetConstraintAsRval(pp, "pid", RVAL_TYPE_SCALAR);
1324-
if (value)
1325-
{
1326-
entries++;
1327-
}
1328-
13291323
if (!IntegerRangeFromString(value, &p.min_pid, &p.max_pid))
13301324
{
13311325
PromiseRef(LOG_LEVEL_ERR, pp);
@@ -1334,11 +1328,6 @@ ProcessSelect GetProcessFilterConstraints(const EvalContext *ctx, const Promise
13341328

13351329
// get constraint parent process ID
13361330
value = PromiseGetConstraintAsRval(pp, "ppid", RVAL_TYPE_SCALAR);
1337-
if (value)
1338-
{
1339-
entries++;
1340-
}
1341-
13421331
if (!IntegerRangeFromString(value, &p.min_ppid, &p.max_ppid))
13431332
{
13441333
PromiseRef(LOG_LEVEL_ERR, pp);
@@ -1347,11 +1336,6 @@ ProcessSelect GetProcessFilterConstraints(const EvalContext *ctx, const Promise
13471336

13481337
// get constraint process group ID
13491338
value = PromiseGetConstraintAsRval(pp, "pgid", RVAL_TYPE_SCALAR);
1350-
if (value)
1351-
{
1352-
entries++;
1353-
}
1354-
13551339
if (!IntegerRangeFromString(value, &p.min_pgid, &p.max_pgid))
13561340
{
13571341
PromiseRef(LOG_LEVEL_ERR, pp);
@@ -1360,11 +1344,6 @@ ProcessSelect GetProcessFilterConstraints(const EvalContext *ctx, const Promise
13601344

13611345
// get constraint resident set size
13621346
value = PromiseGetConstraintAsRval(pp, "rsize", RVAL_TYPE_SCALAR);
1363-
if (value)
1364-
{
1365-
entries++;
1366-
}
1367-
13681347
if (!IntegerRangeFromString(value, &p.min_rsize, &p.max_rsize))
13691348
{
13701349
PromiseRef(LOG_LEVEL_ERR, pp);
@@ -1373,11 +1352,6 @@ ProcessSelect GetProcessFilterConstraints(const EvalContext *ctx, const Promise
13731352

13741353
// get constraint VM size
13751354
value = PromiseGetConstraintAsRval(pp, "vsize", RVAL_TYPE_SCALAR);
1376-
if (value)
1377-
{
1378-
entries++;
1379-
}
1380-
13811355
if (!IntegerRangeFromString(value, &p.min_vsize, &p.max_vsize))
13821356
{
13831357
PromiseRef(LOG_LEVEL_ERR, pp);
@@ -1386,11 +1360,6 @@ ProcessSelect GetProcessFilterConstraints(const EvalContext *ctx, const Promise
13861360

13871361
// get constraint cumulated CPU time
13881362
value = PromiseGetConstraintAsRval(pp, "ttime_range", RVAL_TYPE_SCALAR);
1389-
if (value)
1390-
{
1391-
entries++;
1392-
}
1393-
13941363
if (!IntegerRangeFromString(value, (long *) &p.min_ttime, (long *) &p.max_ttime))
13951364
{
13961365
PromiseRef(LOG_LEVEL_ERR, pp);
@@ -1399,11 +1368,6 @@ ProcessSelect GetProcessFilterConstraints(const EvalContext *ctx, const Promise
13991368

14001369
// get constraint start time
14011370
value = PromiseGetConstraintAsRval(pp, "stime_range", RVAL_TYPE_SCALAR);
1402-
if (value)
1403-
{
1404-
entries++;
1405-
}
1406-
14071371
if (!IntegerRangeFromString(value, (long *) &p.min_stime, (long *) &p.max_stime))
14081372
{
14091373
PromiseRef(LOG_LEVEL_ERR, pp);
@@ -1412,11 +1376,6 @@ ProcessSelect GetProcessFilterConstraints(const EvalContext *ctx, const Promise
14121376

14131377
// get constraint priority
14141378
value = PromiseGetConstraintAsRval(pp, "priority", RVAL_TYPE_SCALAR);
1415-
if (value)
1416-
{
1417-
entries++;
1418-
}
1419-
14201379
if (!IntegerRangeFromString(value, &p.min_pri, &p.max_pri))
14211380
{
14221381
PromiseRef(LOG_LEVEL_ERR, pp);
@@ -1425,11 +1384,6 @@ ProcessSelect GetProcessFilterConstraints(const EvalContext *ctx, const Promise
14251384

14261385
// get constraint threads
14271386
value = PromiseGetConstraintAsRval(pp, "threads", RVAL_TYPE_SCALAR);
1428-
if (value)
1429-
{
1430-
entries++;
1431-
}
1432-
14331387
if (!IntegerRangeFromString(value, &p.min_thread, &p.max_thread))
14341388
{
14351389
PromiseRef(LOG_LEVEL_ERR, pp);
@@ -1442,20 +1396,8 @@ ProcessSelect GetProcessFilterConstraints(const EvalContext *ctx, const Promise
14421396
p.command = PromiseGetConstraintAsRval(pp, "command", RVAL_TYPE_SCALAR);
14431397
p.tty = PromiseGetConstraintAsRval(pp, "tty", RVAL_TYPE_SCALAR);
14441398

1445-
// check if file_result is needed
1446-
if ((p.owner) || (p.status) || (p.command) || (p.tty))
1447-
{
1448-
entries = true;
1449-
}
1450-
14511399
// get constraint process_result
1452-
if ((p.process_result = PromiseGetConstraintAsRval(pp, "process_result", RVAL_TYPE_SCALAR)) == NULL)
1453-
{
1454-
if (entries)
1455-
{
1456-
Log(LOG_LEVEL_ERR, "process_select body missing its process_result return value");
1457-
}
1458-
}
1400+
p.process_result = PromiseGetConstraintAsRval(pp, "process_result", RVAL_TYPE_SCALAR);
14591401

14601402
return p;
14611403
}

libpromises/processes_select.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ static bool SelectProcess(const char *procentry,
151151
assert(a != NULL);
152152

153153
StringSet *process_select_attributes = StringSetNew();
154+
bool unmatched_attribute = false;
154155

155156
memset(column, 0, sizeof(column));
156157

@@ -196,73 +197,130 @@ static bool SelectProcess(const char *procentry,
196197
}
197198
}
198199

200+
if (a->owner && !StringSetContains(process_select_attributes, "process_owner"))
201+
{
202+
unmatched_attribute = true;
203+
}
204+
199205
if (SelectProcRangeMatch("PID", "PID", a->min_pid, a->max_pid, names, column))
200206
{
201207
StringSetAdd(process_select_attributes, xstrdup("pid"));
202208
}
209+
else if (a->min_pid != CF_NOINT)
210+
{
211+
unmatched_attribute = true;
212+
}
203213

204214
if (SelectProcRangeMatch("PPID", "PPID", a->min_ppid, a->max_ppid, names, column))
205215
{
206216
StringSetAdd(process_select_attributes, xstrdup("ppid"));
207217
}
218+
else if (a->min_ppid != CF_NOINT)
219+
{
220+
unmatched_attribute = true;
221+
}
208222

209223
if (SelectProcRangeMatch("PGID", "PGID", a->min_pgid, a->max_pgid, names, column))
210224
{
211225
StringSetAdd(process_select_attributes, xstrdup("pgid"));
212226
}
227+
else if (a->min_pgid != CF_NOINT)
228+
{
229+
unmatched_attribute = true;
230+
}
213231

214232
if (SelectProcRangeMatch("VSZ", "SZ", a->min_vsize, a->max_vsize, names, column))
215233
{
216234
StringSetAdd(process_select_attributes, xstrdup("vsize"));
217235
}
236+
else if (a->min_vsize != CF_NOINT)
237+
{
238+
unmatched_attribute = true;
239+
}
218240

219241
if (SelectProcRangeMatch("RSS", "RSS", a->min_rsize, a->max_rsize, names, column))
220242
{
221243
StringSetAdd(process_select_attributes, xstrdup("rsize"));
222244
}
245+
else if (a->min_rsize != CF_NOINT)
246+
{
247+
unmatched_attribute = true;
248+
}
223249

224250
if (SelectProcTimeCounterRangeMatch("TIME", "TIME", a->min_ttime, a->max_ttime, names, column))
225251
{
226252
StringSetAdd(process_select_attributes, xstrdup("ttime"));
227253
}
254+
else if (a->min_ttime != CF_NOINT)
255+
{
256+
unmatched_attribute = true;
257+
}
228258

229259
if (SelectProcTimeAbsRangeMatch
230260
("STIME", "START", a->min_stime, a->max_stime, names, column))
231261
{
232262
StringSetAdd(process_select_attributes, xstrdup("stime"));
233263
}
264+
else if (a->min_stime != CF_NOINT)
265+
{
266+
unmatched_attribute = true;
267+
}
234268

235269
if (SelectProcRangeMatch("NI", "PRI", a->min_pri, a->max_pri, names, column))
236270
{
237271
StringSetAdd(process_select_attributes, xstrdup("priority"));
238272
}
273+
else if (a->min_pri != CF_NOINT)
274+
{
275+
unmatched_attribute = true;
276+
}
239277

240278
if (SelectProcRangeMatch("NLWP", "NLWP", a->min_thread, a->max_thread, names, column))
241279
{
242280
StringSetAdd(process_select_attributes, xstrdup("threads"));
243281
}
282+
else if (a->min_thread != CF_NOINT)
283+
{
284+
unmatched_attribute = true;
285+
}
244286

245287
if (SelectProcRegexMatch("S", "STAT", a->status, true, names, column))
246288
{
247289
StringSetAdd(process_select_attributes, xstrdup("status"));
248290
}
291+
else if (a->status)
292+
{
293+
unmatched_attribute = true;
294+
}
249295

250296
if (SelectProcRegexMatch("CMD", "COMMAND", a->command, true, names, column))
251297
{
252298
StringSetAdd(process_select_attributes, xstrdup("command"));
253299
}
300+
else if (a->command)
301+
{
302+
unmatched_attribute = true;
303+
}
254304

255305
if (SelectProcRegexMatch("TTY", "TTY", a->tty, true, names, column))
256306
{
257307
StringSetAdd(process_select_attributes, xstrdup("tty"));
258308
}
309+
else if (a->tty)
310+
{
311+
unmatched_attribute = true;
312+
}
259313

260314
if (!a->process_result)
261315
{
262316
if (StringSetSize(process_select_attributes) == 0)
263317
{
264318
result = EvalProcessResult("", process_select_attributes);
265319
}
320+
else if (unmatched_attribute)
321+
{
322+
result = EvalProcessResult("", process_select_attributes);
323+
}
266324
else
267325
{
268326
Writer *w = StringWriter();
@@ -371,6 +429,8 @@ static bool SelectProcRangeMatch(char *name1, char *name2, int min, int max, cha
371429

372430
if ((min <= value) && (value <= max))
373431
{
432+
Log(LOG_LEVEL_VERBOSE, "Selection filter matched absolute '%s/%s' = '%s(%jd)' in [%jd,%jd]", name1, name2, line[i], (intmax_t)value,
433+
(intmax_t)min, (intmax_t)max);
374434
return true;
375435
}
376436
else
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#######################################################
2+
#
3+
# Check process_select bodies without process_result attribute.
4+
#
5+
# If process_select bodies do not have a process_result attribute, its
6+
# given attributes should be AND'ed together for process filtering.
7+
#
8+
# Tests:
9+
#
10+
# 1. Negative: using a highly unlikely virtual memory size range.
11+
#
12+
# 2. Positive: using a virtual memory size range, that should match
13+
# all processes
14+
#
15+
#######################################################
16+
17+
body common control
18+
{
19+
inputs => { "../../default.cf.sub" };
20+
bundlesequence => { default("$(this.promise_filename)") };
21+
version => "1.0";
22+
}
23+
24+
#######################################################
25+
26+
bundle agent init
27+
{
28+
vars:
29+
"dummy" string => "dummy";
30+
}
31+
32+
#######################################################
33+
34+
bundle agent test
35+
{
36+
meta:
37+
# This test exposes a known issue with processes on the Windows platform.
38+
"test_soft_fail" -> {"ENT-12751"}
39+
string => "windows";
40+
41+
"description" -> {"CFE-4511"}
42+
string => "process_select body without process_result";
43+
44+
processes:
45+
### Expect zero processes on a tty with a highly unlikely name.
46+
".*"
47+
handle => "expect_none",
48+
process_select => test_without_process_result("1"),
49+
process_count => test_range("0", "0", "pass_bad_vsize", "fail_bad_vsize");
50+
51+
### Expect to find one or more processes on these ttys.
52+
".*"
53+
handle => "expect_some",
54+
process_select => test_without_process_result("inf"),
55+
process_count => test_range("1", "inf", "pass_good_vsize", "fail_good_vsize");
56+
57+
}
58+
59+
body process_select test_without_process_result(vsize)
60+
{
61+
vsize => "1,$(vsize)";
62+
ppid => "1,1";
63+
}
64+
65+
body process_count test_range(min, max, class_good, class_bad)
66+
{
67+
match_range => irange("$(min)", "$(max)");
68+
in_range_define => { "$(class_good)" };
69+
out_of_range_define => { "$(class_bad)" };
70+
}
71+
72+
#######################################################
73+
74+
bundle agent check
75+
{
76+
classes:
77+
"ok" and => {
78+
"pass_good_vsize", "pass_bad_vsize",
79+
"!fail_good_vsize", "!fail_bad_vsize",
80+
};
81+
82+
reports:
83+
ok::
84+
"$(this.promise_filename) Pass";
85+
!ok::
86+
"$(this.promise_filename) FAIL";
87+
}
88+
89+
### PROJECT_ID: core
90+
### CATEGORY_ID: 30

0 commit comments

Comments
 (0)