[systemd-devel] problem with seeking in the journal

Zbigniew Jędrzejewski-Szmek zbyszek at in.waw.pl
Wed Mar 6 17:50:46 PST 2013


Hi Lennart,

I think I finally found a reproducer for the problem with journalctl
jumping to the beginning. I can't find the bug reports now, but there
certainly were some. I was trying to implement polling the journal in
python, which wasn't working as expected, and then I modified your
example from sd_journal_get_fd(3).

When run as 'seek=t ./polltest' it prints new entries as they come.
When run as './polltest' it waits for an entry, but then prints all
entries from the beginning of the journal. I don't think that it
should.

The difference is in real_journal_next() (around lines 863-866),
called from sd_journal_previous_skip(j, 0) or sd_journal_next_skip(j, 0):
       if (direction == DIRECTION_DOWN)
               found = k < 0;
       else
               found = k > 0;
when seeking "up", found==true, if seeking "down", found==false.

It would be great if you could have a look and clarify if this
is expected behaviour or a bug.


------------------------- polltest.c ------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <systemd/sd-journal.h>

int main(int argc, char *argv[]) {
        int r;
        sd_journal *j;
        r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
        if (r < 0) {
                fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
                return 1;
        }

        /* Opening the fd now means the first sd_journal_wait() will actually wait */
        r = sd_journal_get_fd(j);
        if (r < 0) {
                fprintf(stderr, "Failed to get fd: %s\n", strerror(-r));
                return 1;
        }

        r = sd_journal_seek_tail(j);
        if (r < 0) {
                fprintf(stderr, "Failed to seek tail: %s\n", strerror(-r));
                return 1;
        }

        if (getenv("seek"))
                r = sd_journal_previous_skip(j, 0);
        else
                r = sd_journal_next_skip(j, 0);
        if (r < 0) {
                fprintf(stderr, "Failed to skip: %s\n", strerror(-r));
                return 1;
        }

        r = sd_journal_wait(j, (uint64_t) -1);
        if (r < 0) {
                fprintf(stderr, "Failed to wait for changes: %s\n", strerror(-r));
                return 1;
        }

        for (;;)  {
                const void *d;
                size_t l;
                r = sd_journal_next(j);
                if (r < 0) {
                        fprintf(stderr, "Failed to iterate to next entry: %s\n", strerror(-r));
                        break;
                }
                if (r == 0) {
                        /* Reached the end, let's wait for changes, and try again */
                        r = sd_journal_wait(j, (uint64_t) -1);
                        if (r < 0) {
                                fprintf(stderr, "Failed to wait for changes: %s\n", strerror(-r));
                                break;
                        }
                        continue;
                }
                r = sd_journal_get_data(j, "MESSAGE", &d, &l);
                if (r < 0) {
                        fprintf(stderr, "Failed to read message field: %s\n", strerror(-r));
                        continue;
                }
                printf("%.*s\n", (int) l, (const char*) d);
        }
        sd_journal_close(j);
        return 0;
}

-------------------------------------------------------------------

Thanks,
Zbyszek


More information about the systemd-devel mailing list