[systemd-commits] 2 commits - man/journalctl.xml src/journal src/systemd

Harald Hoyer harald at kemper.freedesktop.org
Wed Apr 17 00:18:35 PDT 2013


 man/journalctl.xml               |    6 +-
 src/journal/journal-internal.h   |    2 
 src/journal/journalctl.c         |   68 +++++++++++++++++++++++----------
 src/journal/sd-journal.c         |   80 +++++++++++++++++++++++++--------------
 src/journal/test-journal-match.c |   16 ++++++-
 src/systemd/sd-journal.h         |    1 
 6 files changed, 122 insertions(+), 51 deletions(-)

New commits:
commit b9e405246e2f3b7149ef1f9924806441d17f004a
Author: Harald Hoyer <harald at redhat.com>
Date:   Fri Apr 12 09:14:43 2013 +0200

    journalctl: specify "--unit=" and "--user-unit" multiple times
    
    Previously only one "--unit=" or "--user-unit" could be specified.
    With this patch, journalcrtl can show multiple units.
    
    $ journalctl -u systemd-udevd.service -u sshd.service -u crond.service -b
    -- Logs begin at Sa 2013-03-23 11:08:45 CET, end at Fr 2013-04-12
    09:10:22 CEST. --
    Apr 12 08:41:37 lenovo systemd[1]: Started udev Kernel Device Manager.
    Apr 12 08:41:37 lenovo systemd[1]: Stopped udev Kernel Device Manager.
    Apr 12 08:41:38 lenovo systemd[1]: Started udev Kernel Device Manager.
    Apr 12 08:41:38 lenovo crond[291]: (CRON) INFO (Syslog will be used
    		instead of sendmail.)
    Apr 12 08:41:38 lenovo crond[291]: (CRON) INFO (running with inotify
    		support)
    Apr 12 08:41:39 lenovo systemd[1]: Starting OpenSSH server daemon...
    Apr 12 08:41:39 lenovo systemd[1]: Started OpenSSH server daemon.
    Apr 12 08:41:39 lenovo sshd[355]: Server listening on 0.0.0.0 port 22.
    Apr 12 08:41:39 lenovo sshd[355]: Server listening on :: port 22.
    Apr 12 08:41:39 lenovo mtp-probe[373]: checking bus 1, device 8:
    "/sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.5/1-1.5.6/1-1.5.6.2/1-1.5.6.2.1"

diff --git a/man/journalctl.xml b/man/journalctl.xml
index 144b54f..91cc322 100644
--- a/man/journalctl.xml
+++ b/man/journalctl.xml
@@ -332,7 +332,8 @@
                                 (<literal>_SYSTEMD_UNIT=</literal>)
                                 and additional matches for messages
                                 from systemd and messages about
-                                coredumps for the specified unit.
+                                coredumps for the specified unit.</para>
+                                <para>This parameter can be specified multiple times.
                                 </para></listitem>
                         </varlistentry>
 
@@ -346,7 +347,8 @@
                                 and <literal>_UID=</literal>) and
                                 additional matches for messages from
                                 session systemd and messages about
-                                coredumps for the specified unit.
+                                coredumps for the specified unit.</para>
+                                <para>This parameter can be specified multiple times.
                                 </para></listitem>
                         </varlistentry>
 
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 2ebac40..68be369 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -80,8 +80,8 @@ static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC;
 #endif
 static usec_t arg_since, arg_until;
 static bool arg_since_set = false, arg_until_set = false;
-static const char *arg_unit = NULL;
-static bool arg_unit_system;
+static char **arg_system_units = NULL;
+static char **arg_user_units = NULL;
 static const char *arg_field = NULL;
 static bool arg_catalog = false;
 static bool arg_reverse = false;
@@ -437,13 +437,15 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'u':
-                        arg_unit = optarg;
-                        arg_unit_system = true;
+                        r = strv_extend(&arg_system_units, optarg);
+                        if (r < 0)
+                                return log_oom();
                         break;
 
                 case ARG_USER_UNIT:
-                        arg_unit = optarg;
-                        arg_unit_system = false;
+                        r = strv_extend(&arg_user_units, optarg);
+                        if (r < 0)
+                                return log_oom();
                         break;
 
                 case '?':
@@ -611,25 +613,39 @@ static int add_this_boot(sd_journal *j) {
         return 0;
 }
 
-static int add_unit(sd_journal *j) {
+static int add_units(sd_journal *j) {
         _cleanup_free_ char *u = NULL;
         int r;
+        char **i;
 
         assert(j);
 
-        if (isempty(arg_unit))
-                return 0;
+        STRV_FOREACH(i, arg_system_units) {
+                u = unit_name_mangle(*i);
+                if (!u)
+                        return log_oom();
+                r = add_matches_for_unit(j, u);
+                if (r < 0)
+                        return r;
+                r = sd_journal_add_disjunction(j);
+                if (r < 0)
+                        return r;
+        }
 
-        u = unit_name_mangle(arg_unit);
-        if (!u)
-                return log_oom();
+        STRV_FOREACH(i, arg_user_units) {
+                u = unit_name_mangle(*i);
+                if (!u)
+                        return log_oom();
 
-        if (arg_unit_system)
-                r = add_matches_for_unit(j, u);
-        else
                 r = add_matches_for_user_unit(j, u, getuid());
-        if (r < 0)
-                return r;
+                if (r < 0)
+                        return r;
+
+                r = sd_journal_add_disjunction(j);
+                if (r < 0)
+                        return r;
+
+        }
 
         r = sd_journal_add_conjunction(j);
         if (r < 0)
@@ -1113,7 +1129,10 @@ int main(int argc, char *argv[]) {
         if (r < 0)
                 return EXIT_FAILURE;
 
-        r = add_unit(j);
+        r = add_units(j);
+        strv_free(arg_system_units);
+        strv_free(arg_user_units);
+
         if (r < 0)
                 return EXIT_FAILURE;
 

commit cd34b3c6670df8a3fd49179131fe762b2dd86b01
Author: Harald Hoyer <harald at redhat.com>
Date:   Thu Apr 11 15:27:55 2013 +0200

    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.

diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h
index ff8b34a..eea56e4 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 c9b2abe..2ebac40 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 7e06a70..cc11ad9 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 2ca2337..7b14568 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 afafee2..51653ba 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);



More information about the systemd-commits mailing list