int main(int argc, char *argv[]) {
        char t[] = "/tmp/journal-XXXXXX";
        unsigned n;
        JournalFile *f;
        const char *verification_key = argv[1];
        usec_t from = 0, to = 0, total = 0;
        char a[FORMAT_TIMESTAMP_MAX];
        char b[FORMAT_TIMESTAMP_MAX];
        char c[FORMAT_TIMESPAN_MAX];
        struct stat st;
        uint64_t p;

        /* journal_file_open requires a valid machine id */
        if (access("/etc/machine-id", F_OK) != 0)
                return EXIT_TEST_SKIP;

        log_set_max_level(LOG_DEBUG);

        assert_se(mkdtemp(t));
        assert_se(chdir(t) >= 0);

        log_info("Generating...");

        assert_se(journal_file_open(-1, "test.journal", O_RDWR|O_CREAT, 0666, true, !!verification_key, NULL, NULL, NULL, NULL, &f) == 0);

        for (n = 0; n < N_ENTRIES; n++) {
                struct iovec iovec;
                struct dual_timestamp ts;
                char *test;

                dual_timestamp_get(&ts);

                assert_se(asprintf(&test, "RANDOM=%lu", random() % RANDOM_RANGE));

                iovec.iov_base = (void*) test;
                iovec.iov_len = strlen(test);

                assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0);

                free(test);
        }

        (void) journal_file_close(f);

        log_info("Verifying...");

        assert_se(journal_file_open(-1, "test.journal", O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, NULL, &f) == 0);
        /* journal_file_print_header(f); */
        journal_file_dump(f);

        assert_se(journal_file_verify(f, verification_key, &from, &to, &total, true) >= 0);

        if (verification_key && JOURNAL_HEADER_SEALED(f->header))
                log_info("=> Validated from %s to %s, %s missing",
                         format_timestamp(a, sizeof(a), from),
                         format_timestamp(b, sizeof(b), to),
                         format_timespan(c, sizeof(c), total > to ? total - to : 0, 0));

        (void) journal_file_close(f);

        if (verification_key) {
                log_info("Toggling bits...");

                assert_se(stat("test.journal", &st) >= 0);

                for (p = 38448*8+0; p < ((uint64_t) st.st_size * 8); p ++) {
                        bit_toggle("test.journal", p);

                        log_info("[ %"PRIu64"+%"PRIu64"]", p / 8, p % 8);

                        if (raw_verify("test.journal", verification_key) >= 0)
                                log_notice(ANSI_HIGHLIGHT_RED ">>>> %"PRIu64" (bit %"PRIu64") can be toggled without detection." ANSI_NORMAL, p / 8, p % 8);

                        bit_toggle("test.journal", p);
                }
        }

        log_info("Exiting...");

        assert_se(rm_rf(t, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);

        return 0;
}
示例#2
0
static void test_non_empty(void) {
        dual_timestamp ts;
        JournalFile *f;
        struct iovec iovec;
        static const char test[] = "TEST1=1", test2[] = "TEST2=2";
        Object *o;
        uint64_t p;
        sd_id128_t fake_boot_id;
        char t[] = "/tmp/journal-XXXXXX";

        test_setup_logging(LOG_DEBUG);

        assert_se(mkdtemp(t));
        assert_se(chdir(t) >= 0);

        assert_se(journal_file_open(-1, "test.journal", O_RDWR|O_CREAT, 0666, true, (uint64_t) -1, true, NULL, NULL, NULL, NULL, &f) == 0);

        assert_se(dual_timestamp_get(&ts));
        assert_se(sd_id128_randomize(&fake_boot_id) == 0);

        iovec.iov_base = (void*) test;
        iovec.iov_len = strlen(test);
        assert_se(journal_file_append_entry(f, &ts, NULL, &iovec, 1, NULL, NULL, NULL) == 0);

        iovec.iov_base = (void*) test2;
        iovec.iov_len = strlen(test2);
        assert_se(journal_file_append_entry(f, &ts, NULL, &iovec, 1, NULL, NULL, NULL) == 0);

        iovec.iov_base = (void*) test;
        iovec.iov_len = strlen(test);
        assert_se(journal_file_append_entry(f, &ts, &fake_boot_id, &iovec, 1, NULL, NULL, NULL) == 0);

#if HAVE_GCRYPT
        journal_file_append_tag(f);
#endif
        journal_file_dump(f);

        assert_se(journal_file_next_entry(f, 0, DIRECTION_DOWN, &o, &p) == 1);
        assert_se(le64toh(o->entry.seqnum) == 1);

        assert_se(journal_file_next_entry(f, p, DIRECTION_DOWN, &o, &p) == 1);
        assert_se(le64toh(o->entry.seqnum) == 2);

        assert_se(journal_file_next_entry(f, p, DIRECTION_DOWN, &o, &p) == 1);
        assert_se(le64toh(o->entry.seqnum) == 3);
        assert_se(sd_id128_equal(o->entry.boot_id, fake_boot_id));

        assert_se(journal_file_next_entry(f, p, DIRECTION_DOWN, &o, &p) == 0);

        assert_se(journal_file_next_entry(f, 0, DIRECTION_DOWN, &o, &p) == 1);
        assert_se(le64toh(o->entry.seqnum) == 1);

        assert_se(journal_file_find_data_object(f, test, strlen(test), NULL, &p) == 1);
        assert_se(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_DOWN, &o, NULL) == 1);
        assert_se(le64toh(o->entry.seqnum) == 1);

        assert_se(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_UP, &o, NULL) == 1);
        assert_se(le64toh(o->entry.seqnum) == 3);

        assert_se(journal_file_find_data_object(f, test2, strlen(test2), NULL, &p) == 1);
        assert_se(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_UP, &o, NULL) == 1);
        assert_se(le64toh(o->entry.seqnum) == 2);

        assert_se(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_DOWN, &o, NULL) == 1);
        assert_se(le64toh(o->entry.seqnum) == 2);

        assert_se(journal_file_find_data_object(f, "quux", 4, NULL, &p) == 0);

        assert_se(journal_file_move_to_entry_by_seqnum(f, 1, DIRECTION_DOWN, &o, NULL) == 1);
        assert_se(le64toh(o->entry.seqnum) == 1);

        assert_se(journal_file_move_to_entry_by_seqnum(f, 3, DIRECTION_DOWN, &o, NULL) == 1);
        assert_se(le64toh(o->entry.seqnum) == 3);

        assert_se(journal_file_move_to_entry_by_seqnum(f, 2, DIRECTION_DOWN, &o, NULL) == 1);
        assert_se(le64toh(o->entry.seqnum) == 2);

        assert_se(journal_file_move_to_entry_by_seqnum(f, 10, DIRECTION_DOWN, &o, NULL) == 0);

        journal_file_rotate(&f, true, (uint64_t) -1, true, NULL);
        journal_file_rotate(&f, true, (uint64_t) -1, true, NULL);

        (void) journal_file_close(f);

        log_info("Done...");

        if (arg_keep)
                log_info("Not removing %s", t);
        else {
                journal_directory_vacuum(".", 3000000, 0, 0, NULL, true);

                assert_se(rm_rf(t, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
        }

        puts("------------------------------------------------------------");
}
int main(int argc, char *argv[]) {
    JournalFile *one, *two, *three;
    char t[] = "/tmp/journal-stream-XXXXXX";
    unsigned i;
    _cleanup_journal_close_ sd_journal *j = NULL;
    char *z;
    const void *data;
    size_t l;

    /* journal_file_open requires a valid machine id */
    if (access("/etc/machine-id", F_OK) != 0)
        return EXIT_TEST_SKIP;

    log_set_max_level(LOG_DEBUG);

    assert_se(mkdtemp(t));
    assert_se(chdir(t) >= 0);

    assert_se(journal_file_open("one.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &one) == 0);
    assert_se(journal_file_open("two.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &two) == 0);
    assert_se(journal_file_open("three.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &three) == 0);

    for (i = 0; i < N_ENTRIES; i++) {
        char *p, *q;
        dual_timestamp ts;
        struct iovec iovec[2];

        dual_timestamp_get(&ts);

        assert_se(asprintf(&p, "NUMBER=%u", i) >= 0);
        iovec[0].iov_base = p;
        iovec[0].iov_len = strlen(p);

        assert_se(asprintf(&q, "MAGIC=%s", i % 5 == 0 ? "quux" : "waldo") >= 0);

        iovec[1].iov_base = q;
        iovec[1].iov_len = strlen(q);

        if (i % 10 == 0)
            assert_se(journal_file_append_entry(three, &ts, iovec, 2, NULL, NULL, NULL) == 0);
        else {
            if (i % 3 == 0)
                assert_se(journal_file_append_entry(two, &ts, iovec, 2, NULL, NULL, NULL) == 0);

            assert_se(journal_file_append_entry(one, &ts, iovec, 2, NULL, NULL, NULL) == 0);
        }

        free(p);
        free(q);
    }

    journal_file_close(one);
    journal_file_close(two);
    journal_file_close(three);

    assert_se(sd_journal_open_directory(&j, t, 0) >= 0);

    assert_se(sd_journal_add_match(j, "MAGIC=quux", 0) >= 0);
    SD_JOURNAL_FOREACH_BACKWARDS(j) {
        _cleanup_free_ char *c;

        assert_se(sd_journal_get_data(j, "NUMBER", &data, &l) >= 0);
        printf("\t%.*s\n", (int) l, (const char*) data);

        assert_se(sd_journal_get_cursor(j, &c) >= 0);
        assert_se(sd_journal_test_cursor(j, c) > 0);
    }

    SD_JOURNAL_FOREACH(j) {
        _cleanup_free_ char *c;

        assert_se(sd_journal_get_data(j, "NUMBER", &data, &l) >= 0);
        printf("\t%.*s\n", (int) l, (const char*) data);

        assert_se(sd_journal_get_cursor(j, &c) >= 0);
        assert_se(sd_journal_test_cursor(j, c) > 0);
    }

    sd_journal_flush_matches(j);

    verify_contents(j, 1);

    printf("NEXT TEST\n");
    assert_se(sd_journal_add_match(j, "MAGIC=quux", 0) >= 0);

    assert_se(z = journal_make_match_string(j));
    printf("resulting match expression is: %s\n", z);
    free(z);

    verify_contents(j, 5);

    printf("NEXT TEST\n");
    sd_journal_flush_matches(j);
    assert_se(sd_journal_add_match(j, "MAGIC=waldo", 0) >= 0);
    assert_se(sd_journal_add_match(j, "NUMBER=10", 0) >= 0);
    assert_se(sd_journal_add_match(j, "NUMBER=11", 0) >= 0);
    assert_se(sd_journal_add_match(j, "NUMBER=12", 0) >= 0);

    assert_se(z = journal_make_match_string(j));
    printf("resulting match expression is: %s\n", z);
    free(z);

    verify_contents(j, 0);

    assert_se(sd_journal_query_unique(j, "NUMBER") >= 0);
    SD_JOURNAL_FOREACH_UNIQUE(j, data, l)
    printf("%.*s\n", (int) l, (const char*) data);

    assert_se(rm_rf_dangerous(t, false, true, false) >= 0);

    return 0;
}