journal: implement multiple field matches

This commit is contained in:
Lennart Poettering 2011-11-08 18:20:03 +01:00
parent 9b3c575ed9
commit de190aef08
10 changed files with 1676 additions and 682 deletions

View File

@ -31,9 +31,10 @@ typedef struct Header Header;
typedef struct ObjectHeader ObjectHeader;
typedef union Object Object;
typedef struct DataObject DataObject;
typedef struct FieldObject FieldObject;
typedef struct EntryObject EntryObject;
typedef struct HashTableObject HashTableObject;
typedef struct BisectTableObject BisectTableObject;
typedef struct EntryArrayObject EntryArrayObject;
typedef struct EntryItem EntryItem;
typedef struct HashItem HashItem;
@ -41,9 +42,12 @@ typedef struct HashItem HashItem;
enum {
OBJECT_UNUSED,
OBJECT_DATA,
OBJECT_FIELD,
OBJECT_ENTRY,
OBJECT_HASH_TABLE,
OBJECT_BISECT_TABLE
OBJECT_DATA_HASH_TABLE,
OBJECT_FIELD_HASH_TABLE,
OBJECT_ENTRY_ARRAY,
_OBJECT_TYPE_MAX
};
_packed_ struct ObjectHeader {
@ -56,18 +60,26 @@ _packed_ struct ObjectHeader {
_packed_ struct DataObject {
ObjectHeader object;
uint64_t hash;
uint64_t head_entry_offset;
uint64_t tail_entry_offset;
uint64_t prev_hash_offset;
uint64_t next_hash_offset;
uint64_t next_field_offset;
uint64_t entry_offset; /* the first array entry we store inline */
uint64_t entry_array_offset;
uint64_t n_entries;
uint8_t payload[];
};
_packed_ struct FieldObject {
ObjectHeader object;
uint64_t hash;
uint64_t next_hash_offset;
uint64_t head_data_offset;
uint64_t tail_data_offset;
uint8_t payload[];
};
_packed_ struct EntryItem {
uint64_t object_offset;
uint64_t hash;
uint64_t prev_entry_offset;
uint64_t next_entry_offset;
};
_packed_ struct EntryObject {
@ -77,8 +89,6 @@ _packed_ struct EntryObject {
uint64_t monotonic;
sd_id128_t boot_id;
uint64_t xor_hash;
uint64_t prev_entry_offset;
uint64_t next_entry_offset;
EntryItem items[];
};
@ -89,20 +99,22 @@ _packed_ struct HashItem {
_packed_ struct HashTableObject {
ObjectHeader object;
HashItem table[];
HashItem items[];
};
_packed_ struct BisectTableObject {
_packed_ struct EntryArrayObject {
ObjectHeader object;
uint64_t table[];
uint64_t next_entry_array_offset;
uint64_t items[];
};
union Object {
ObjectHeader object;
DataObject data;
FieldObject field;
EntryObject entry;
HashTableObject hash_table;
BisectTableObject bisect_table;
EntryArrayObject entry_array;
};
enum {
@ -115,30 +127,30 @@ _packed_ struct Header {
uint8_t signature[8]; /* "LPKSHHRH" */
uint32_t compatible_flags;
uint32_t incompatible_flags;
uint32_t state;
uint8_t reserved[4];
uint8_t state;
uint8_t reserved[7];
sd_id128_t file_id;
sd_id128_t machine_id;
sd_id128_t boot_id;
sd_id128_t seqnum_id;
uint64_t arena_offset;
uint64_t arena_size;
uint64_t arena_max_size;
uint64_t arena_min_size;
uint64_t arena_keep_free;
uint64_t hash_table_offset; /* for looking up data objects */
uint64_t hash_table_size;
uint64_t bisect_table_offset; /* for looking up entry objects */
uint64_t bisect_table_size;
uint64_t head_object_offset;
uint64_t arena_max_size; /* obsolete */
uint64_t arena_min_size; /* obsolete */
uint64_t arena_keep_free; /* obsolete */
uint64_t data_hash_table_offset; /* for looking up data objects */
uint64_t data_hash_table_size;
uint64_t field_hash_table_offset; /* for looking up field objects */
uint64_t field_hash_table_size;
uint64_t tail_object_offset;
uint64_t head_entry_offset;
uint64_t tail_entry_offset;
uint64_t last_bisect_offset;
uint64_t n_objects;
uint64_t n_entries;
uint64_t seqnum;
uint64_t first_seqnum;
uint64_t entry_array_offset;
uint64_t head_entry_realtime;
uint64_t tail_entry_realtime;
uint64_t tail_entry_monotonic;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,23 @@
#include "util.h"
#include "sd-id128.h"
typedef struct Window {
void *ptr;
uint64_t offset;
uint64_t size;
} Window;
enum {
WINDOW_UNKNOWN = OBJECT_UNUSED,
WINDOW_DATA = OBJECT_DATA,
WINDOW_ENTRY = OBJECT_ENTRY,
WINDOW_DATA_HASH_TABLE = OBJECT_DATA_HASH_TABLE,
WINDOW_FIELD_HASH_TABLE = OBJECT_FIELD_HASH_TABLE,
WINDOW_ENTRY_ARRAY = OBJECT_ENTRY_ARRAY,
WINDOW_HEADER,
_WINDOW_MAX
};
typedef struct JournalFile {
int fd;
char *path;
@ -36,20 +53,13 @@ typedef struct JournalFile {
int flags;
int prot;
bool writable;
bool tail_entry_monotonic_valid;
Header *header;
HashItem *data_hash_table;
HashItem *field_hash_table;
HashItem *hash_table;
void *hash_table_window;
uint64_t hash_table_window_size;
uint64_t *bisect_table;
void *bisect_table_window;
uint64_t bisect_table_window_size;
void *window;
uint64_t window_offset;
uint64_t window_size;
Window windows[_WINDOW_MAX];
uint64_t current_offset;
} JournalFile;
@ -60,20 +70,28 @@ typedef enum direction {
} direction_t;
int journal_file_open(const char *fname, int flags, mode_t mode, JournalFile *template, JournalFile **ret);
void journal_file_close(JournalFile *j);
int journal_file_move_to_object(JournalFile *f, uint64_t offset, int type, Object **ret);
int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Object **ret);
uint64_t journal_file_entry_n_items(Object *o);
int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const struct iovec iovec[], unsigned n_iovec, uint64_t *seqno, Object **ret, uint64_t *offset);
int journal_file_move_to_entry(JournalFile *f, uint64_t seqnum, Object **ret, uint64_t *offset);
int journal_file_find_data_object(JournalFile *f, const void *data, uint64_t size, Object **ret, uint64_t *offset);
int journal_file_find_data_object_with_hash(JournalFile *f, const void *data, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset);
int journal_file_find_first_entry(JournalFile *f, const void *data, uint64_t size, direction_t direction, Object **ret, uint64_t *offset);
int journal_file_next_entry(JournalFile *f, Object *o, uint64_t p, direction_t direction, Object **ret, uint64_t *offset);
int journal_file_skip_entry(JournalFile *f, Object *o, uint64_t p, int64_t skip, Object **ret, uint64_t *offset);
int journal_file_next_entry(JournalFile *f, Object *o, direction_t direction, Object **ret, uint64_t *offset);
int journal_file_next_entry_for_data(JournalFile *f, Object *o, uint64_t p, uint64_t data_offset, direction_t direction, Object **ret, uint64_t *offset);
int journal_file_move_to_entry_by_seqnum(JournalFile *f, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset);
int journal_file_move_to_entry_by_realtime(JournalFile *f, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset);
int journal_file_move_to_entry_by_monotonic(JournalFile *f, sd_id128_t boot_id, uint64_t monotonic, direction_t direction, Object **ret, uint64_t *offset);
int journal_file_move_to_entry_by_seqnum_for_data(JournalFile *f, uint64_t data_offset, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset);
int journal_file_move_to_entry_by_realtime_for_data(JournalFile *f, uint64_t data_offset, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset);
void journal_file_dump(JournalFile *f);
@ -81,5 +99,4 @@ int journal_file_rotate(JournalFile **f);
int journal_directory_vacuum(const char *directory, uint64_t max_use, uint64_t min_free);
#endif

View File

@ -54,7 +54,7 @@ int main(int argc, char *argv[]) {
}
}
SD_JOURNAL_FOREACH_BEGIN(j) {
SD_JOURNAL_FOREACH(j) {
const void *data;
size_t length;
@ -71,7 +71,7 @@ int main(int argc, char *argv[]) {
free(cursor);
sd_journal_get_realtime_usec(j, &realtime);
sd_journal_get_monotonic_usec(j, &monotonic);
sd_journal_get_monotonic_usec(j, &monotonic, NULL);
printf("realtime: %llu\n"
"monotonic: %llu\n",
(unsigned long long) realtime,
@ -80,7 +80,7 @@ int main(int argc, char *argv[]) {
SD_JOURNAL_FOREACH_DATA(j, data, length)
printf("\t%.*s\n", (int) length, (const char*) data);
} SD_JOURNAL_FOREACH_END(j);
}
finish:
if (j)

View File

@ -144,14 +144,14 @@ static void process_message(Server *s, const char *buf, struct ucred *ucred, str
*audit_session = NULL, *audit_loginuid = NULL,
*syslog_priority = NULL, *syslog_facility = NULL,
*exe = NULL, *cgroup = NULL;
struct iovec iovec[16];
struct iovec iovec[17];
unsigned n = 0;
char idbuf[33];
sd_id128_t id;
int r;
char *t;
int priority = LOG_USER | LOG_INFO;
uid_t loginuid = 0;
uid_t loginuid = 0, realuid = 0;
JournalFile *f;
parse_syslog_priority((char**) &buf, &priority);
@ -171,18 +171,20 @@ static void process_message(Server *s, const char *buf, struct ucred *ucred, str
uint32_t session;
char *path;
if (asprintf(&pid, "PID=%lu", (unsigned long) ucred->pid) >= 0)
realuid = ucred->uid;
if (asprintf(&pid, "_PID=%lu", (unsigned long) ucred->pid) >= 0)
IOVEC_SET_STRING(iovec[n++], pid);
if (asprintf(&uid, "UID=%lu", (unsigned long) ucred->uid) >= 0)
if (asprintf(&uid, "_UID=%lu", (unsigned long) ucred->uid) >= 0)
IOVEC_SET_STRING(iovec[n++], uid);
if (asprintf(&gid, "GID=%lu", (unsigned long) ucred->gid) >= 0)
if (asprintf(&gid, "_GID=%lu", (unsigned long) ucred->gid) >= 0)
IOVEC_SET_STRING(iovec[n++], gid);
r = get_process_comm(ucred->pid, &t);
if (r >= 0) {
comm = strappend("COMM=", t);
comm = strappend("_COMM=", t);
if (comm)
IOVEC_SET_STRING(iovec[n++], comm);
free(t);
@ -190,7 +192,7 @@ static void process_message(Server *s, const char *buf, struct ucred *ucred, str
r = get_process_exe(ucred->pid, &t);
if (r >= 0) {
exe = strappend("EXE=", t);
exe = strappend("_EXE=", t);
if (comm)
IOVEC_SET_STRING(iovec[n++], exe);
free(t);
@ -198,7 +200,7 @@ static void process_message(Server *s, const char *buf, struct ucred *ucred, str
r = get_process_cmdline(ucred->pid, LINE_MAX, false, &t);
if (r >= 0) {
cmdline = strappend("CMDLINE=", t);
cmdline = strappend("_CMDLINE=", t);
if (cmdline)
IOVEC_SET_STRING(iovec[n++], cmdline);
free(t);
@ -206,17 +208,17 @@ static void process_message(Server *s, const char *buf, struct ucred *ucred, str
r = audit_session_from_pid(ucred->pid, &session);
if (r >= 0)
if (asprintf(&audit_session, "AUDIT_SESSION=%lu", (unsigned long) session) >= 0)
if (asprintf(&audit_session, "_AUDIT_SESSION=%lu", (unsigned long) session) >= 0)
IOVEC_SET_STRING(iovec[n++], audit_session);
r = audit_loginuid_from_pid(ucred->pid, &loginuid);
if (r >= 0)
if (asprintf(&audit_loginuid, "AUDIT_LOGINUID=%lu", (unsigned long) loginuid) >= 0)
if (asprintf(&audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid) >= 0)
IOVEC_SET_STRING(iovec[n++], audit_loginuid);
r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, ucred->pid, &path);
if (r >= 0) {
cgroup = strappend("SYSTEMD_CGROUP=", path);
cgroup = strappend("_SYSTEMD_CGROUP=", path);
if (cgroup)
IOVEC_SET_STRING(iovec[n++], cgroup);
free(path);
@ -224,7 +226,7 @@ static void process_message(Server *s, const char *buf, struct ucred *ucred, str
}
if (tv) {
if (asprintf(&source_time, "SOURCE_REALTIME_TIMESTAMP=%llu",
if (asprintf(&source_time, "_SOURCE_REALTIME_TIMESTAMP=%llu",
(unsigned long long) timeval_load(tv)) >= 0)
IOVEC_SET_STRING(iovec[n++], source_time);
}
@ -234,23 +236,23 @@ static void process_message(Server *s, const char *buf, struct ucred *ucred, str
* anyway. However, we need this indexed, too. */
r = sd_id128_get_boot(&id);
if (r >= 0)
if (asprintf(&boot_id, "BOOT_ID=%s", sd_id128_to_string(id, idbuf)) >= 0)
if (asprintf(&boot_id, "_BOOT_ID=%s", sd_id128_to_string(id, idbuf)) >= 0)
IOVEC_SET_STRING(iovec[n++], boot_id);
r = sd_id128_get_machine(&id);
if (r >= 0)
if (asprintf(&machine_id, "MACHINE_ID=%s", sd_id128_to_string(id, idbuf)) >= 0)
if (asprintf(&machine_id, "_MACHINE_ID=%s", sd_id128_to_string(id, idbuf)) >= 0)
IOVEC_SET_STRING(iovec[n++], machine_id);
t = gethostname_malloc();
if (t) {
hostname = strappend("HOSTNAME=", t);
hostname = strappend("_HOSTNAME=", t);
if (hostname)
IOVEC_SET_STRING(iovec[n++], hostname);
free(t);
}
f = find_journal(s, loginuid);
f = find_journal(s, realuid == 0 ? 0 : loginuid);
if (!f)
log_warning("Dropping message, as we can't find a place to store the data.");
else {

File diff suppressed because it is too large Load Diff

View File

@ -25,18 +25,22 @@
#include <inttypes.h>
#include <sys/types.h>
#include "sd-id128.h"
/* TODO:
*
* - check LE/BE conversion for 8bit, 16bit, 32bit values
* - implement parallel traversal
* - implement inotify usage on client
* - implement audit gateway
* - implement native gateway
* - implement stdout gateway
* - extend hash table/bisect table as we go
* - extend hash tables table as we go
* - accelerate looking for "all hostnames" and suchlike.
* - throttling
* - enforce limit on open journal files in journald and journalctl
* - cryptographic hash
* - fix space reservation logic
* - comm, argv can be manipulated, should it be _COMM=, _CMDLINE= or COMM=, CMDLINE=?
*/
typedef struct sd_journal sd_journal;
@ -47,59 +51,52 @@ void sd_journal_close(sd_journal *j);
int sd_journal_previous(sd_journal *j);
int sd_journal_next(sd_journal *j);
int sd_journal_previous_skip(sd_journal *j, uint64_t skip);
int sd_journal_next_skip(sd_journal *j, uint64_t skip);
int sd_journal_get_realtime_usec(sd_journal *j, uint64_t *ret);
int sd_journal_get_monotonic_usec(sd_journal *j, uint64_t *ret);
int sd_journal_get_monotonic_usec(sd_journal *j, uint64_t *ret, sd_id128_t *ret_boot_id);
int sd_journal_get_data(sd_journal *j, const char *field, const void **data, size_t *l);
int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t *l);
void sd_journal_start_data(sd_journal *j);
void sd_journal_restart_data(sd_journal *j);
int sd_journal_add_match(sd_journal *j, const void *data, size_t size);
void sd_journal_flush_matches(sd_journal *j);
int sd_journal_seek_head(sd_journal *j);
int sd_journal_seek_tail(sd_journal *j);
int sd_journal_seek_monotonic_usec(sd_journal *j, uint64_t usec); /* missing */
int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec); /* missing */
int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t usec);
int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec);
int sd_journal_seek_cursor(sd_journal *j, const char *cursor);
int sd_journal_get_cursor(sd_journal *j, char **cursor);
int sd_journal_set_cursor(sd_journal *j, const char *cursor); /* missing */
int sd_journal_unique_seek(sd_journal *j, const char *field); /* missing */
int sd_journal_unique_enumerate(sd_journal *j, const void **data, size_t *l); /* missing */
int sd_journal_get_fd(sd_journal *j); /* missing */
int sd_journal_query_unique(sd_journal *j, const char *field); /* missing */
int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_t *l); /* missing */
void sd_journal_restart_unique(sd_journal *j); /* missing */
enum {
SD_JOURNAL_NOP,
SD_JOURNAL_APPEND,
SD_JOURNAL_DROP
SD_JOURNAL_INVALIDATE_ADD,
SD_JOURNAL_INVALIDATE_REMOVE
};
int sd_journal_get_fd(sd_journal *j); /* missing */
int sd_journal_process(sd_journal *j); /* missing */
#define SD_JOURNAL_FOREACH_BEGIN(j) \
if (sd_journal_seek_head(j) > 0) do {
#define SD_JOURNAL_FOREACH(j) \
if (sd_journal_seek_head(j) >= 0) \
while (sd_journal_next(j) > 0) \
#define SD_JOURNAL_FOREACH_END(j) \
} while (sd_journal_next(j) > 0)
#define SD_JOURNAL_FOREACH_CONTINUE(j) \
do {
#define SD_JOURNAL_FOREACH_BACKWARDS_BEGIN(j) \
if (sd_journal_seek_tail(j) > 0) do {
#define SD_JOURNAL_FOREACH_BACKWARDS_END(j) \
} while (sd_journal_previous(j) > 0)
#define SD_JOURNAL_FOREACH_BACKWARDS_CONTINUE(j) \
do {
#define SD_JOURNAL_FOREACH_BACKWARDS(j) \
if (sd_journal_seek_tail(j) >= 0) \
while (sd_journal_previous(j) > 0) \
#define SD_JOURNAL_FOREACH_DATA(j, data, l) \
for (sd_journal_start_data(j); sd_journal_enumerate_data((j), &(data), &(l)) > 0; )
for (sd_journal_restart_data(j); sd_journal_enumerate_data((j), &(data), &(l)) > 0; )
#define SD_JOURNAL_FOREACH_UNIQUE(j, data, l) \
while (sd_journal_enumerate_unique_data((j), &(data), &(l)) > 0)
#define SD_JOURNAL_FOREACH_UNIQUE(j, data, l) \
for (sd_journal_restart_unique(j); sd_journal_enumerate_data((j), &(data), &(l)) > 0; )
#endif

View File

@ -31,6 +31,7 @@ int main(int argc, char *argv[]) {
struct iovec iovec;
static const char test[] = "test", test2[] = "test2";
Object *o;
uint64_t p;
log_set_max_level(LOG_DEBUG);
@ -54,41 +55,55 @@ int main(int argc, char *argv[]) {
journal_file_dump(f);
assert(journal_file_next_entry(f, NULL, DIRECTION_DOWN, &o, NULL) == 1);
assert(journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, &o, &p) == 1);
assert(le64toh(o->entry.seqnum) == 1);
assert(journal_file_next_entry(f, o, DIRECTION_DOWN, &o, NULL) == 1);
assert(journal_file_next_entry(f, o, p, DIRECTION_DOWN, &o, &p) == 1);
assert(le64toh(o->entry.seqnum) == 2);
assert(journal_file_next_entry(f, o, DIRECTION_DOWN, &o, NULL) == 1);
assert(journal_file_next_entry(f, o, p, DIRECTION_DOWN, &o, &p) == 1);
assert(le64toh(o->entry.seqnum) == 3);
assert(journal_file_next_entry(f, o, DIRECTION_DOWN, &o, NULL) == 0);
assert(journal_file_next_entry(f, o, p, DIRECTION_DOWN, &o, &p) == 0);
assert(journal_file_find_first_entry(f, test, strlen(test), DIRECTION_DOWN, &o, NULL) == 1);
assert(journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, &o, &p) == 1);
assert(le64toh(o->entry.seqnum) == 1);
assert(journal_file_find_first_entry(f, test, strlen(test), DIRECTION_UP, &o, NULL) == 1);
assert(journal_file_skip_entry(f, o, p, 2, &o, &p) == 1);
assert(le64toh(o->entry.seqnum) == 3);
assert(journal_file_find_first_entry(f, test2, strlen(test2), DIRECTION_UP, &o, NULL) == 1);
assert(le64toh(o->entry.seqnum) == 2);
assert(journal_file_find_first_entry(f, test2, strlen(test2), DIRECTION_DOWN, &o, NULL) == 1);
assert(le64toh(o->entry.seqnum) == 2);
assert(journal_file_find_first_entry(f, "quux", 4, DIRECTION_DOWN, &o, NULL) == 0);
assert(journal_file_move_to_entry(f, 1, &o, NULL) == 1);
assert(journal_file_skip_entry(f, o, p, -2, &o, &p) == 1);
assert(le64toh(o->entry.seqnum) == 1);
assert(journal_file_move_to_entry(f, 3, &o, NULL) == 1);
assert(journal_file_skip_entry(f, o, p, -2, &o, &p) == 1);
assert(le64toh(o->entry.seqnum) == 1);
assert(journal_file_find_data_object(f, test, strlen(test), NULL, &p) == 1);
assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_DOWN, &o, NULL) == 1);
assert(le64toh(o->entry.seqnum) == 1);
assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_UP, &o, NULL) == 1);
assert(le64toh(o->entry.seqnum) == 3);
assert(journal_file_move_to_entry(f, 2, &o, NULL) == 1);
assert(journal_file_find_data_object(f, test2, strlen(test2), NULL, &p) == 1);
assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_UP, &o, NULL) == 1);
assert(le64toh(o->entry.seqnum) == 2);
assert(journal_file_move_to_entry(f, 10, &o, NULL) == 0);
assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_DOWN, &o, NULL) == 1);
assert(le64toh(o->entry.seqnum) == 2);
assert(journal_file_find_data_object(f, "quux", 4, NULL, &p) == 0);
assert(journal_file_move_to_entry_by_seqnum(f, 1, DIRECTION_DOWN, &o, NULL) == 1);
assert(le64toh(o->entry.seqnum) == 1);
assert(journal_file_move_to_entry_by_seqnum(f, 3, DIRECTION_DOWN, &o, NULL) == 1);
assert(le64toh(o->entry.seqnum) == 3);
assert(journal_file_move_to_entry_by_seqnum(f, 2, DIRECTION_DOWN, &o, NULL) == 1);
assert(le64toh(o->entry.seqnum) == 2);
assert(journal_file_move_to_entry_by_seqnum(f, 10, DIRECTION_DOWN, &o, NULL) == 0);
journal_file_rotate(&f);
journal_file_rotate(&f);

View File

@ -1,57 +0,0 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2011 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "wjournal.h"
#include "journal-def.h"
struct WJournal {
int fd;
Header *header;
HashItem *hash_table;
uint64_t *bisect_table;
};
int wjournal_open(const char *fn, WJournal **ret) {
assert(fn);
assert(ret);
}
void wjournal_close(WJournal *j) {
assert(j);
if (j->fd >= 0)
close_nointr_nofail(j->fd);
if (j->header) {
munmap(j->header, PAGE_ALIGN(sizeof(Header)));
}
free(j);
}
int wjournal_write_object_begin(WJournal *j, uint64_t type, uint64_t size, Object **ret);
int wjournal_write_object_finish(WJournal *j, Object *ret);
int wjournal_write_field(WJournal *j, const char *buffer, uint64_t size, Object **ret);
int wjournal_write_entry(WJournal *j, const Field *fields, unsigned n_fields, Object **ret);
int wjournal_write_eof(WJournal *j);

View File

@ -1,39 +0,0 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#ifndef foojournalhfoo
#define foojournalhfoo
/***
This file is part of systemd.
Copyright 2011 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <inttypes.h>
typedef struct WJournal WJournal;
int wjournal_open(const char *fn, WJournal **ret);
void wjournal_close(WJournal *j);
int wjournal_write_object_begin(WJournal *j, uint64_t type, uint64_t size, Object **ret);
int wjournal_write_object_finish(WJournal *j, Object *ret);
int wjournal_write_field(WJournal *j, const char *buffer, uint64_t size, Object **ret);
int wjournal_write_entry(WJournal *j, const Field *fields, unsigned n_fields, Object **ret);
int wjournal_write_eof(WJournal *j);
#endif