Skip to content

Commit cd34b3c

Browse files
committed
journal: add one more level on top with AND
When using "-p" and "-b" in combination with "-u", the output is not what you would expect. The reason is the sd_journal_add_disjunction() call in add_matches_for_unit() and add_matches_for_user_unit(), which adds two ORs without taking the other conditions to every OR. Adding another level on top with AND and sd_journal_add_conjunction() solves the problem. Output before: $ journalctl -o short-monotonic -ab -p 0 -u sshd.service -- Reboot -- [ 3.216305] lenovo systemd[1]: Starting OpenSSH server daemon... -- Reboot -- [ 3.168666] lenovo systemd[1]: Starting OpenSSH server daemon... [ 3.169639] lenovo systemd[1]: Started OpenSSH server daemon. [36285.635389] lenovo systemd[1]: Stopped OpenSSH server daemon. -- Reboot -- [ 10.838657] lenovo systemd[1]: Starting OpenSSH server daemon... [ 10.913698] lenovo systemd[1]: Started OpenSSH server daemon. [ 6881.035183] lenovo systemd[1]: Stopped OpenSSH server daemon. -- Reboot -- [ 6.636228] lenovo systemd[1]: Starting OpenSSH server daemon... [ 6.662573] lenovo systemd[1]: Started OpenSSH server daemon. [ 6.681148] lenovo sshd[397]: Server listening on 0.0.0.0 port 22. [ 6.681379] lenovo sshd[397]: Server listening on :: port 22. As we see, the output is from _every_ boot and priority 0 is not taken into account. Output after patch: $ journalctl -o short-monotonic -ab -p 0 -u sshd.service -- Logs begin at Sun 2013-02-24 20:54:44 CET, end at Tue 2013-03-19 14:58:21 CET. -- Increasing the priority: $ journalctl -o short-monotonic -ab -p 6 -u sshd.service -- Logs begin at Sun 2013-02-24 20:54:44 CET, end at Tue 2013-03-19 14:59:12 CET. -- [ 6.636228] lenovo systemd[1]: Starting OpenSSH server daemon... [ 6.662573] lenovo systemd[1]: Started OpenSSH server daemon. [ 6.681148] lenovo sshd[397]: Server listening on 0.0.0.0 port 22. [ 6.681379] lenovo sshd[397]: Server listening on :: port 22.
1 parent 003ac9d commit cd34b3c

File tree

5 files changed

+83
-33
lines changed

5 files changed

+83
-33
lines changed

src/journal/journal-internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ struct sd_journal {
113113

114114
int inotify_fd;
115115

116-
Match *level0, *level1;
116+
Match *level0, *level1, *level2;
117117

118118
unsigned current_invalidate_counter, last_invalidate_counter;
119119

src/journal/journalctl.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,10 @@ static int add_this_boot(sd_journal *j) {
604604
return r;
605605
}
606606

607+
r = sd_journal_add_conjunction(j);
608+
if (r < 0)
609+
return r;
610+
607611
return 0;
608612
}
609613

@@ -627,13 +631,16 @@ static int add_unit(sd_journal *j) {
627631
if (r < 0)
628632
return r;
629633

634+
r = sd_journal_add_conjunction(j);
635+
if (r < 0)
636+
return r;
637+
630638
return 0;
631639
}
632640

633641
static int add_priorities(sd_journal *j) {
634642
char match[] = "PRIORITY=0";
635643
int i, r;
636-
637644
assert(j);
638645

639646
if (arg_priorities == 0xFF)
@@ -650,6 +657,10 @@ static int add_priorities(sd_journal *j) {
650657
}
651658
}
652659

660+
r = sd_journal_add_conjunction(j);
661+
if (r < 0)
662+
return r;
663+
653664
return 0;
654665
}
655666

@@ -1106,11 +1117,11 @@ int main(int argc, char *argv[]) {
11061117
if (r < 0)
11071118
return EXIT_FAILURE;
11081119

1109-
r = add_matches(j, argv + optind);
1120+
r = add_priorities(j);
11101121
if (r < 0)
11111122
return EXIT_FAILURE;
11121123

1113-
r = add_priorities(j);
1124+
r = add_matches(j, argv + optind);
11141125
if (r < 0)
11151126
return EXIT_FAILURE;
11161127

src/journal/sd-journal.c

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ static void match_free_if_empty(Match *m) {
203203
}
204204

205205
_public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size) {
206-
Match *l2, *l3, *add_here = NULL, *m;
206+
Match *l3, *l4, *add_here = NULL, *m;
207207
le64_t le_hash;
208208

209209
if (!j)
@@ -218,44 +218,52 @@ _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size)
218218
if (!match_is_valid(data, size))
219219
return -EINVAL;
220220

221-
/* level 0: OR term
222-
* level 1: AND terms
223-
* level 2: OR terms
224-
* level 3: concrete matches */
221+
/* level 0: AND term
222+
* level 1: OR terms
223+
* level 2: AND terms
224+
* level 3: OR terms
225+
* level 4: concrete matches */
225226

226227
if (!j->level0) {
227-
j->level0 = match_new(NULL, MATCH_OR_TERM);
228+
j->level0 = match_new(NULL, MATCH_AND_TERM);
228229
if (!j->level0)
229230
return -ENOMEM;
230231
}
231232

232233
if (!j->level1) {
233-
j->level1 = match_new(j->level0, MATCH_AND_TERM);
234+
j->level1 = match_new(j->level0, MATCH_OR_TERM);
234235
if (!j->level1)
235236
return -ENOMEM;
236237
}
237238

238-
assert(j->level0->type == MATCH_OR_TERM);
239-
assert(j->level1->type == MATCH_AND_TERM);
239+
if (!j->level2) {
240+
j->level2 = match_new(j->level1, MATCH_AND_TERM);
241+
if (!j->level2)
242+
return -ENOMEM;
243+
}
244+
245+
assert(j->level0->type == MATCH_AND_TERM);
246+
assert(j->level1->type == MATCH_OR_TERM);
247+
assert(j->level2->type == MATCH_AND_TERM);
240248

241249
le_hash = htole64(hash64(data, size));
242250

243-
LIST_FOREACH(matches, l2, j->level1->matches) {
244-
assert(l2->type == MATCH_OR_TERM);
251+
LIST_FOREACH(matches, l3, j->level2->matches) {
252+
assert(l3->type == MATCH_OR_TERM);
245253

246-
LIST_FOREACH(matches, l3, l2->matches) {
247-
assert(l3->type == MATCH_DISCRETE);
254+
LIST_FOREACH(matches, l4, l3->matches) {
255+
assert(l4->type == MATCH_DISCRETE);
248256

249257
/* Exactly the same match already? Then ignore
250258
* this addition */
251-
if (l3->le_hash == le_hash &&
252-
l3->size == size &&
253-
memcmp(l3->data, data, size) == 0)
259+
if (l4->le_hash == le_hash &&
260+
l4->size == size &&
261+
memcmp(l4->data, data, size) == 0)
254262
return 0;
255263

256264
/* Same field? Then let's add this to this OR term */
257-
if (same_field(data, size, l3->data, l3->size)) {
258-
add_here = l2;
265+
if (same_field(data, size, l4->data, l4->size)) {
266+
add_here = l3;
259267
break;
260268
}
261269
}
@@ -265,7 +273,7 @@ _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size)
265273
}
266274

267275
if (!add_here) {
268-
add_here = match_new(j->level1, MATCH_OR_TERM);
276+
add_here = match_new(j->level2, MATCH_OR_TERM);
269277
if (!add_here)
270278
goto fail;
271279
}
@@ -288,6 +296,9 @@ _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size)
288296
if (add_here)
289297
match_free_if_empty(add_here);
290298

299+
if (j->level2)
300+
match_free_if_empty(j->level2);
301+
291302
if (j->level1)
292303
match_free_if_empty(j->level1);
293304

@@ -297,9 +308,7 @@ _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size)
297308
return -ENOMEM;
298309
}
299310

300-
_public_ int sd_journal_add_disjunction(sd_journal *j) {
301-
Match *m;
302-
311+
_public_ int sd_journal_add_conjunction(sd_journal *j) {
303312
assert(j);
304313

305314
if (!j->level0)
@@ -311,11 +320,28 @@ _public_ int sd_journal_add_disjunction(sd_journal *j) {
311320
if (!j->level1->matches)
312321
return 0;
313322

314-
m = match_new(j->level0, MATCH_AND_TERM);
315-
if (!m)
316-
return -ENOMEM;
323+
j->level1 = NULL;
324+
j->level2 = NULL;
325+
326+
return 0;
327+
}
328+
329+
_public_ int sd_journal_add_disjunction(sd_journal *j) {
330+
assert(j);
331+
332+
if (!j->level0)
333+
return 0;
334+
335+
if (!j->level1)
336+
return 0;
337+
338+
if (!j->level2)
339+
return 0;
340+
341+
if (!j->level2->matches)
342+
return 0;
317343

318-
j->level1 = m;
344+
j->level2 = NULL;
319345
return 0;
320346
}
321347

@@ -380,7 +406,7 @@ _public_ void sd_journal_flush_matches(sd_journal *j) {
380406
if (j->level0)
381407
match_free(j->level0);
382408

383-
j->level0 = j->level1 = NULL;
409+
j->level0 = j->level1 = j->level2 = NULL;
384410

385411
detach_location(j);
386412
}

src/journal/test-journal-match.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,23 @@ int main(int argc, char *argv[]) {
5454
assert_se(sd_journal_add_match(j, "ONE=two", 0) >= 0);
5555
assert_se(sd_journal_add_match(j, "TWO=two", 0) >= 0);
5656

57-
assert_se(t = journal_make_match_string(j));
57+
assert_se(sd_journal_add_conjunction(j) >= 0);
58+
59+
assert_se(sd_journal_add_match(j, "L4_1=yes", 0) >= 0);
60+
assert_se(sd_journal_add_match(j, "L4_1=ok", 0) >= 0);
61+
assert_se(sd_journal_add_match(j, "L4_2=yes", 0) >= 0);
62+
assert_se(sd_journal_add_match(j, "L4_2=ok", 0) >= 0);
63+
64+
assert_se(sd_journal_add_disjunction(j) >= 0);
5865

59-
assert_se(streq(t, "((TWO=two AND (ONE=two OR ONE=one)) OR (PIFF=paff AND (QUUX=yyyyy OR QUUX=xxxxx OR QUUX=mmmm) AND (HALLO= OR HALLO=WALDO)))"));
66+
assert_se(sd_journal_add_match(j, "L3=yes", 0) >= 0);
67+
assert_se(sd_journal_add_match(j, "L3=ok", 0) >= 0);
68+
69+
assert_se(t = journal_make_match_string(j));
6070

6171
printf("resulting match expression is: %s\n", t);
6272

73+
assert_se(streq(t, "(((L3=ok OR L3=yes) OR ((L4_2=ok OR L4_2=yes) AND (L4_1=ok OR L4_1=yes))) AND ((TWO=two AND (ONE=two OR ONE=one)) OR (PIFF=paff AND (QUUX=yyyyy OR QUUX=xxxxx OR QUUX=mmmm) AND (HALLO= OR HALLO=WALDO))))"));
74+
6375
return 0;
6476
}

src/systemd/sd-journal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ void sd_journal_restart_data(sd_journal *j);
106106

107107
int sd_journal_add_match(sd_journal *j, const void *data, size_t size);
108108
int sd_journal_add_disjunction(sd_journal *j);
109+
int sd_journal_add_conjunction(sd_journal *j);
109110
void sd_journal_flush_matches(sd_journal *j);
110111

111112
int sd_journal_seek_head(sd_journal *j);

0 commit comments

Comments
 (0)