Esempio n. 1
0
static void test_empty(void) {
        JournalFile *f1, *f2, *f3, *f4;
        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, false, (uint64_t) -1, false, NULL, NULL, NULL, NULL, &f1) == 0);

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

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

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

        journal_file_print_header(f1);
        puts("");
        journal_file_print_header(f2);
        puts("");
        journal_file_print_header(f3);
        puts("");
        journal_file_print_header(f4);
        puts("");

        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);
        }

        (void) journal_file_close(f1);
        (void) journal_file_close(f2);
        (void) journal_file_close(f3);
        (void) journal_file_close(f4);
}
Esempio n. 2
0
static int raw_verify(const char *fn, const char *verification_key) {
        JournalFile *f;
        int r;

        r = journal_file_open(fn, O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f);
        if (r < 0)
                return r;

        r = journal_file_verify(f, verification_key, NULL, NULL, NULL, false);
        journal_file_close(f);

        return r;
}
int main(int argc, char *argv[]) {
        _cleanup_free_ char *fn = NULL;
        char dn[] = "/var/tmp/test-journal-flush.XXXXXX";
        JournalFile *new_journal = NULL;
        sd_journal *j = NULL;
        unsigned n = 0;
        int r;

        assert_se(mkdtemp(dn));
        fn = strappend(dn, "/test.journal");

        r = journal_file_open(-1, fn, O_CREAT|O_RDWR, 0644, false, false, NULL, NULL, NULL, NULL, &new_journal);
        assert_se(r >= 0);

        r = sd_journal_open(&j, 0);
        assert_se(r >= 0);

        sd_journal_set_data_threshold(j, 0);

        SD_JOURNAL_FOREACH(j) {
                Object *o;
                JournalFile *f;

                f = j->current_file;
                assert_se(f && f->current_offset > 0);

                r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
                assert_se(r >= 0);

                r = journal_file_copy_entry(f, new_journal, o, f->current_offset, NULL, NULL, NULL);
                assert_se(r >= 0);

                n++;
                if (n > 10000)
                        break;
        }

        sd_journal_close(j);

        (void) journal_file_close(new_journal);

        unlink(fn);
        assert_se(rmdir(dn) == 0);

        return 0;
}
Esempio n. 4
0
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;

        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, NULL, NULL, NULL, &one) == 0);
        assert_se(journal_file_open("two.journal", O_RDWR|O_CREAT, 0666, true, NULL, NULL, NULL, &two) == 0);
        assert_se(journal_file_open("three.journal", O_RDWR|O_CREAT, 0666, true, 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 = NULL;

                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 = NULL;

                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;
}
Esempio n. 5
0
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("test.journal", O_RDWR|O_CREAT, 0666, true, !!verification_key, 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);
        }

        journal_file_close(f);

        log_info("Verifying...");

        assert_se(journal_file_open("test.journal", O_RDONLY, 0666, true, !!verification_key, 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));

        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;
}
static JournalFile *test_open (const char *name)
{
    JournalFile *f;
    assert_ret(journal_file_open(name, O_RDWR|O_CREAT, 0644, true, false, NULL, NULL, NULL, &f));
    return f;
}
static void test_sequence_numbers(void) {

    char t[] = "/tmp/journal-seq-XXXXXX";
    JournalFile *one, *two;
    uint64_t seqnum = 0;
    sd_id128_t seqnum_id;

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

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

    append_number(one, 1, &seqnum);
    printf("seqnum=%"PRIu64"\n", seqnum);
    assert(seqnum == 1);
    append_number(one, 2, &seqnum);
    printf("seqnum=%"PRIu64"\n", seqnum);
    assert(seqnum == 2);

    assert(one->header->state == STATE_ONLINE);
    assert(!sd_id128_equal(one->header->file_id, one->header->machine_id));
    assert(!sd_id128_equal(one->header->file_id, one->header->boot_id));
    assert(sd_id128_equal(one->header->file_id, one->header->seqnum_id));

    memcpy(&seqnum_id, &one->header->seqnum_id, sizeof(sd_id128_t));

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

    assert(two->header->state == STATE_ONLINE);
    assert(!sd_id128_equal(two->header->file_id, one->header->file_id));
    assert(sd_id128_equal(one->header->machine_id, one->header->machine_id));
    assert(sd_id128_equal(one->header->boot_id, one->header->boot_id));
    assert(sd_id128_equal(one->header->seqnum_id, one->header->seqnum_id));

    append_number(two, 3, &seqnum);
    printf("seqnum=%"PRIu64"\n", seqnum);
    assert(seqnum == 3);
    append_number(two, 4, &seqnum);
    printf("seqnum=%"PRIu64"\n", seqnum);
    assert(seqnum == 4);

    test_close(two);

    append_number(one, 5, &seqnum);
    printf("seqnum=%"PRIu64"\n", seqnum);
    assert(seqnum == 5);

    append_number(one, 6, &seqnum);
    printf("seqnum=%"PRIu64"\n", seqnum);
    assert(seqnum == 6);

    test_close(one);

    /* restart server */
    seqnum = 0;

    assert_se(journal_file_open("two.journal", O_RDWR, 0,
                                true, false, NULL, NULL, NULL, &two) == 0);

    assert(sd_id128_equal(two->header->seqnum_id, seqnum_id));

    append_number(two, 7, &seqnum);
    printf("seqnum=%"PRIu64"\n", seqnum);
    assert(seqnum == 5);

    /* So..., here we have the same seqnum in two files with the
     * same seqnum_id. */

    test_close(two);

    log_info("Done...");

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

        assert_se(rm_rf_dangerous(t, false, true, false) >= 0);
    }
}
Esempio n. 8
0
static bool check_compressed(uint64_t compress_threshold, uint64_t data_size) {
        dual_timestamp ts;
        JournalFile *f;
        struct iovec iovec;
        Object *o;
        uint64_t p;
        char t[] = "/tmp/journal-XXXXXX";
        char data[2048] = {0};
        bool is_compressed;
        int r;

        assert_se(data_size <= sizeof(data));

        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, compress_threshold, true, NULL, NULL, NULL, NULL, &f) == 0);

        dual_timestamp_get(&ts);

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

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

        /* We have to partially reimplement some of the dump logic, because the normal next_entry does the
         * decompression for us. */
        p = le64toh(f->header->header_size);
        for (;;) {
                r = journal_file_move_to_object(f, OBJECT_UNUSED, p, &o);
                assert_se(r == 0);
                if (o->object.type == OBJECT_DATA)
                        break;

                assert_se(p < le64toh(f->header->tail_object_offset));
                p = p + ALIGN64(le64toh(o->object.size));
        }

        is_compressed = (o->object.flags & OBJECT_COMPRESSION_MASK) != 0;

        (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("------------------------------------------------------------");

        return is_compressed;
}
Esempio n. 9
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("------------------------------------------------------------");
}
Esempio n. 10
0
int
main(int argc, char **argv)
{
	gfarm_error_t e;
	int exit_code = EXIT_SUCCESS;
	int opt_list = 0;
	int opt_max_seqnum_only = 0;
	int c, eof;
	const char *path;
	journal_post_read_op_t post_read = post_read_aggregate;

	if (argc > 0)
		program_name = basename(argv[0]);
	gflog_initialize();

	while ((c = getopt(argc, argv, "dhlmrv?")) != -1) {
		switch (c) {
		case 'd':
			gflog_set_message_verbose(2);
			gflog_set_priority_level(LOG_DEBUG);
			break;
		case 'l':
			opt_list = 1;
			post_read = post_read_list;
			break;
		case 'm':
			opt_max_seqnum_only = 1;
			break;
		case 'v':
			opt_verbose = 1;
			break;
		case 'r':
			opt_record_only = 1;
			break;
		case 'h':
		case '?':
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (argc < 1)
		usage();
	path = argv[0];

	if ((e = journal_file_open(path, 0, GFARM_METADB_SERVER_SEQNUM_INVALID,
	    &jf, GFARM_JOURNAL_RDONLY)) != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s : %s\n", program_name,
		    gfarm_error_string(e));
		exit_code = EXIT_FAILURE;
		goto end;
	}

	reader = journal_file_main_reader(jf);

	if (opt_list && !opt_record_only && !opt_max_seqnum_only) {
		printf(
		    "seqnum       operation              "
		    "length  ");
		if (opt_verbose)
			printf("offset     ");
		printf("argument\n");
	}

	while ((e = db_journal_read(reader, reader, post_read, NULL, &eof))
		== GFARM_ERR_NO_ERROR && eof == 0)
		;
	ave_reclen = num_rec > 0 ? ave_reclen / num_rec : 0;
	if (num_rec == 0)
		min_seqnum = 0;
	if (opt_max_seqnum_only)
		printf("%" GFARM_PRId64 "\n", max_seqnum);
	else if (!opt_record_only) {
		if (opt_list)
			printf("\n");
		printf("records  seqnum(min/max)            "
		    "record length(min/max/ave)\n"
		    "%7lu  %12" GFARM_PRId64 "/%12" GFARM_PRId64
		    "     %7lu/%7lu/%7lu\n",
		     (unsigned long)num_rec, min_seqnum, max_seqnum,
		     (unsigned long)min_reclen, (unsigned long)max_reclen,
		     (unsigned long)ave_reclen);
	}
	if (e != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s : %s\n", program_name,
		    gfarm_error_string(e));
		exit_code = EXIT_FAILURE;
	}
end:
	journal_file_close(jf);
	gflog_terminate();
	return (exit_code);
}