mirror of
https://github.com/systemd/systemd.git
synced 2025-01-27 18:04:05 +03:00
journal: implement multiple field matches
This commit is contained in:
parent
9b3c575ed9
commit
de190aef08
@ -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
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user