summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/journal/journal-internal.h2
-rw-r--r--src/journal/journalctl.c17
-rw-r--r--src/journal/sd-journal.c80
-rw-r--r--src/journal/test-journal-match.c16
-rw-r--r--src/systemd/sd-journal.h1
5 files changed, 83 insertions, 33 deletions
diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h
index ff8b34a951..eea56e4713 100644
--- a/src/journal/journal-internal.h
+++ b/src/journal/journal-internal.h
@@ -113,7 +113,7 @@ struct sd_journal {
int inotify_fd;
- Match *level0, *level1;
+ Match *level0, *level1, *level2;
unsigned current_invalidate_counter, last_invalidate_counter;
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index c9b2abecea..2ebac405c2 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -604,6 +604,10 @@ static int add_this_boot(sd_journal *j) {
return r;
}
+ r = sd_journal_add_conjunction(j);
+ if (r < 0)
+ return r;
+
return 0;
}
@@ -627,13 +631,16 @@ static int add_unit(sd_journal *j) {
if (r < 0)
return r;
+ r = sd_journal_add_conjunction(j);
+ if (r < 0)
+ return r;
+
return 0;
}
static int add_priorities(sd_journal *j) {
char match[] = "PRIORITY=0";
int i, r;
-
assert(j);
if (arg_priorities == 0xFF)
@@ -650,6 +657,10 @@ static int add_priorities(sd_journal *j) {
}
}
+ r = sd_journal_add_conjunction(j);
+ if (r < 0)
+ return r;
+
return 0;
}
@@ -1106,11 +1117,11 @@ int main(int argc, char *argv[]) {
if (r < 0)
return EXIT_FAILURE;
- r = add_matches(j, argv + optind);
+ r = add_priorities(j);
if (r < 0)
return EXIT_FAILURE;
- r = add_priorities(j);
+ r = add_matches(j, argv + optind);
if (r < 0)
return EXIT_FAILURE;
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 7e06a70344..cc11ad9b56 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -203,7 +203,7 @@ static void match_free_if_empty(Match *m) {
}
_public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size) {
- Match *l2, *l3, *add_here = NULL, *m;
+ Match *l3, *l4, *add_here = NULL, *m;
le64_t le_hash;
if (!j)
@@ -218,44 +218,52 @@ _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size)
if (!match_is_valid(data, size))
return -EINVAL;
- /* level 0: OR term
- * level 1: AND terms
- * level 2: OR terms
- * level 3: concrete matches */
+ /* level 0: AND term
+ * level 1: OR terms
+ * level 2: AND terms
+ * level 3: OR terms
+ * level 4: concrete matches */
if (!j->level0) {
- j->level0 = match_new(NULL, MATCH_OR_TERM);
+ j->level0 = match_new(NULL, MATCH_AND_TERM);
if (!j->level0)
return -ENOMEM;
}
if (!j->level1) {
- j->level1 = match_new(j->level0, MATCH_AND_TERM);
+ j->level1 = match_new(j->level0, MATCH_OR_TERM);
if (!j->level1)
return -ENOMEM;
}
- assert(j->level0->type == MATCH_OR_TERM);
- assert(j->level1->type == MATCH_AND_TERM);
+ if (!j->level2) {
+ j->level2 = match_new(j->level1, MATCH_AND_TERM);
+ if (!j->level2)
+ return -ENOMEM;
+ }
+
+ assert(j->level0->type == MATCH_AND_TERM);
+ assert(j->level1->type == MATCH_OR_TERM);
+ assert(j->level2->type == MATCH_AND_TERM);
le_hash = htole64(hash64(data, size));
- LIST_FOREACH(matches, l2, j->level1->matches) {
- assert(l2->type == MATCH_OR_TERM);
+ LIST_FOREACH(matches, l3, j->level2->matches) {
+ assert(l3->type == MATCH_OR_TERM);
- LIST_FOREACH(matches, l3, l2->matches) {
- assert(l3->type == MATCH_DISCRETE);
+ LIST_FOREACH(matches, l4, l3->matches) {
+ assert(l4->type == MATCH_DISCRETE);
/* Exactly the same match already? Then ignore
* this addition */
- if (l3->le_hash == le_hash &&
- l3->size == size &&
- memcmp(l3->data, data, size) == 0)
+ if (l4->le_hash == le_hash &&
+ l4->size == size &&
+ memcmp(l4->data, data, size) == 0)
return 0;
/* Same field? Then let's add this to this OR term */
- if (same_field(data, size, l3->data, l3->size)) {
- add_here = l2;
+ if (same_field(data, size, l4->data, l4->size)) {
+ add_here = l3;
break;
}
}
@@ -265,7 +273,7 @@ _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size)
}
if (!add_here) {
- add_here = match_new(j->level1, MATCH_OR_TERM);
+ add_here = match_new(j->level2, MATCH_OR_TERM);
if (!add_here)
goto fail;
}
@@ -288,6 +296,9 @@ fail:
if (add_here)
match_free_if_empty(add_here);
+ if (j->level2)
+ match_free_if_empty(j->level2);
+
if (j->level1)
match_free_if_empty(j->level1);
@@ -297,9 +308,7 @@ fail:
return -ENOMEM;
}
-_public_ int sd_journal_add_disjunction(sd_journal *j) {
- Match *m;
-
+_public_ int sd_journal_add_conjunction(sd_journal *j) {
assert(j);
if (!j->level0)
@@ -311,11 +320,28 @@ _public_ int sd_journal_add_disjunction(sd_journal *j) {
if (!j->level1->matches)
return 0;
- m = match_new(j->level0, MATCH_AND_TERM);
- if (!m)
- return -ENOMEM;
+ j->level1 = NULL;
+ j->level2 = NULL;
+
+ return 0;
+}
+
+_public_ int sd_journal_add_disjunction(sd_journal *j) {
+ assert(j);
+
+ if (!j->level0)
+ return 0;
+
+ if (!j->level1)
+ return 0;
+
+ if (!j->level2)
+ return 0;
+
+ if (!j->level2->matches)
+ return 0;
- j->level1 = m;
+ j->level2 = NULL;
return 0;
}
@@ -380,7 +406,7 @@ _public_ void sd_journal_flush_matches(sd_journal *j) {
if (j->level0)
match_free(j->level0);
- j->level0 = j->level1 = NULL;
+ j->level0 = j->level1 = j->level2 = NULL;
detach_location(j);
}
diff --git a/src/journal/test-journal-match.c b/src/journal/test-journal-match.c
index 2ca2337c44..7b14568fd2 100644
--- a/src/journal/test-journal-match.c
+++ b/src/journal/test-journal-match.c
@@ -54,11 +54,23 @@ int main(int argc, char *argv[]) {
assert_se(sd_journal_add_match(j, "ONE=two", 0) >= 0);
assert_se(sd_journal_add_match(j, "TWO=two", 0) >= 0);
- assert_se(t = journal_make_match_string(j));
+ assert_se(sd_journal_add_conjunction(j) >= 0);
+
+ assert_se(sd_journal_add_match(j, "L4_1=yes", 0) >= 0);
+ assert_se(sd_journal_add_match(j, "L4_1=ok", 0) >= 0);
+ assert_se(sd_journal_add_match(j, "L4_2=yes", 0) >= 0);
+ assert_se(sd_journal_add_match(j, "L4_2=ok", 0) >= 0);
+
+ assert_se(sd_journal_add_disjunction(j) >= 0);
- 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)))"));
+ assert_se(sd_journal_add_match(j, "L3=yes", 0) >= 0);
+ assert_se(sd_journal_add_match(j, "L3=ok", 0) >= 0);
+
+ assert_se(t = journal_make_match_string(j));
printf("resulting match expression is: %s\n", t);
+ 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))))"));
+
return 0;
}
diff --git a/src/systemd/sd-journal.h b/src/systemd/sd-journal.h
index afafee2d82..51653bafe9 100644
--- a/src/systemd/sd-journal.h
+++ b/src/systemd/sd-journal.h
@@ -106,6 +106,7 @@ void sd_journal_restart_data(sd_journal *j);
int sd_journal_add_match(sd_journal *j, const void *data, size_t size);
int sd_journal_add_disjunction(sd_journal *j);
+int sd_journal_add_conjunction(sd_journal *j);
void sd_journal_flush_matches(sd_journal *j);
int sd_journal_seek_head(sd_journal *j);