|
|
|
@@ -33,6 +33,7 @@
|
|
|
|
|
#include "list.h"
|
|
|
|
|
#include "lookup3.h"
|
|
|
|
|
#include "nulstr-util.h"
|
|
|
|
|
#include "origin-id.h"
|
|
|
|
|
#include "path-util.h"
|
|
|
|
|
#include "prioq.h"
|
|
|
|
|
#include "process-util.h"
|
|
|
|
@@ -51,19 +52,12 @@
|
|
|
|
|
|
|
|
|
|
#define DEFAULT_DATA_THRESHOLD (64*1024)
|
|
|
|
|
|
|
|
|
|
DEFINE_PRIVATE_ORIGIN_ID_HELPERS(sd_journal, journal);
|
|
|
|
|
|
|
|
|
|
static void remove_file_real(sd_journal *j, JournalFile *f);
|
|
|
|
|
static int journal_file_read_tail_timestamp(sd_journal *j, JournalFile *f);
|
|
|
|
|
static void journal_file_unlink_newest_by_bood_id(sd_journal *j, JournalFile *f);
|
|
|
|
|
|
|
|
|
|
static bool journal_pid_changed(sd_journal *j) {
|
|
|
|
|
assert(j);
|
|
|
|
|
|
|
|
|
|
/* We don't support people creating a journal object and
|
|
|
|
|
* keeping it around over a fork(). Let's complain. */
|
|
|
|
|
|
|
|
|
|
return j->original_pid != getpid_cached();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int journal_put_error(sd_journal *j, int r, const char *path) {
|
|
|
|
|
_cleanup_free_ char *copy = NULL;
|
|
|
|
|
int k;
|
|
|
|
@@ -234,7 +228,7 @@ _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size)
|
|
|
|
|
uint64_t hash;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
assert_return(data, -EINVAL);
|
|
|
|
|
|
|
|
|
|
if (size == 0)
|
|
|
|
@@ -330,7 +324,7 @@ fail:
|
|
|
|
|
|
|
|
|
|
_public_ int sd_journal_add_conjunction(sd_journal *j) {
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
|
|
|
|
|
if (!j->level0)
|
|
|
|
|
return 0;
|
|
|
|
@@ -349,7 +343,7 @@ _public_ int sd_journal_add_conjunction(sd_journal *j) {
|
|
|
|
|
|
|
|
|
|
_public_ int sd_journal_add_disjunction(sd_journal *j) {
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
|
|
|
|
|
if (!j->level0)
|
|
|
|
|
return 0;
|
|
|
|
@@ -406,7 +400,7 @@ char *journal_make_match_string(sd_journal *j) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_public_ void sd_journal_flush_matches(sd_journal *j) {
|
|
|
|
|
if (!j)
|
|
|
|
|
if (!j || journal_origin_changed(j))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (j->level0)
|
|
|
|
@@ -930,7 +924,7 @@ static int real_journal_next(sd_journal *j, direction_t direction) {
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
|
|
|
|
|
r = iterated_cache_get(j->files_cache, NULL, &files, &n_files);
|
|
|
|
|
if (r < 0)
|
|
|
|
@@ -988,7 +982,7 @@ static int real_journal_next_skip(sd_journal *j, direction_t direction, uint64_t
|
|
|
|
|
int c = 0, r;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
assert_return(skip <= INT_MAX, -ERANGE);
|
|
|
|
|
|
|
|
|
|
if (skip == 0) {
|
|
|
|
@@ -1031,7 +1025,7 @@ _public_ int sd_journal_get_cursor(sd_journal *j, char **cursor) {
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
assert_return(cursor, -EINVAL);
|
|
|
|
|
|
|
|
|
|
if (!j->current_file || j->current_file->current_offset <= 0)
|
|
|
|
@@ -1064,7 +1058,7 @@ _public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) {
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!isempty(cursor), -EINVAL);
|
|
|
|
|
|
|
|
|
|
for (const char *p = cursor;;) {
|
|
|
|
@@ -1160,7 +1154,7 @@ _public_ int sd_journal_test_cursor(sd_journal *j, const char *cursor) {
|
|
|
|
|
Object *o;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!isempty(cursor), -EINVAL);
|
|
|
|
|
|
|
|
|
|
if (!j->current_file || j->current_file->current_offset <= 0)
|
|
|
|
@@ -1239,7 +1233,7 @@ _public_ int sd_journal_test_cursor(sd_journal *j, const char *cursor) {
|
|
|
|
|
|
|
|
|
|
_public_ int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t usec) {
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
|
|
|
|
|
detach_location(j);
|
|
|
|
|
|
|
|
|
@@ -1255,7 +1249,7 @@ _public_ int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, u
|
|
|
|
|
|
|
|
|
|
_public_ int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec) {
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
|
|
|
|
|
detach_location(j);
|
|
|
|
|
|
|
|
|
@@ -1270,7 +1264,7 @@ _public_ int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec) {
|
|
|
|
|
|
|
|
|
|
_public_ int sd_journal_seek_head(sd_journal *j) {
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
|
|
|
|
|
detach_location(j);
|
|
|
|
|
|
|
|
|
@@ -1283,7 +1277,7 @@ _public_ int sd_journal_seek_head(sd_journal *j) {
|
|
|
|
|
|
|
|
|
|
_public_ int sd_journal_seek_tail(sd_journal *j) {
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
|
|
|
|
|
detach_location(j);
|
|
|
|
|
|
|
|
|
@@ -2001,7 +1995,7 @@ static sd_journal *journal_new(int flags, const char *path, const char *namespac
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
*j = (sd_journal) {
|
|
|
|
|
.original_pid = getpid_cached(),
|
|
|
|
|
.origin_id = origin_id_query(),
|
|
|
|
|
.toplevel_fd = -EBADF,
|
|
|
|
|
.inotify_fd = -EBADF,
|
|
|
|
|
.flags = flags,
|
|
|
|
@@ -2254,7 +2248,7 @@ _public_ void sd_journal_close(sd_journal *j) {
|
|
|
|
|
Directory *d;
|
|
|
|
|
Prioq *p;
|
|
|
|
|
|
|
|
|
|
if (!j)
|
|
|
|
|
if (!j || journal_origin_changed(j))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
while ((p = hashmap_first(j->newest_by_boot_id)))
|
|
|
|
@@ -2470,7 +2464,7 @@ _public_ int sd_journal_get_realtime_usec(sd_journal *j, uint64_t *ret) {
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
|
|
|
|
|
f = j->current_file;
|
|
|
|
|
if (!f)
|
|
|
|
@@ -2498,7 +2492,7 @@ _public_ int sd_journal_get_monotonic_usec(sd_journal *j, uint64_t *ret, sd_id12
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
|
|
|
|
|
f = j->current_file;
|
|
|
|
|
if (!f)
|
|
|
|
@@ -2543,7 +2537,7 @@ _public_ int sd_journal_get_seqnum(
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
|
|
|
|
|
f = j->current_file;
|
|
|
|
|
if (!f)
|
|
|
|
@@ -2597,7 +2591,7 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
assert_return(field, -EINVAL);
|
|
|
|
|
assert_return(data, -EINVAL);
|
|
|
|
|
assert_return(size, -EINVAL);
|
|
|
|
@@ -2654,7 +2648,7 @@ _public_ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
assert_return(data, -EINVAL);
|
|
|
|
|
assert_return(size, -EINVAL);
|
|
|
|
|
|
|
|
|
@@ -2715,7 +2709,7 @@ _public_ int sd_journal_enumerate_available_data(sd_journal *j, const void **dat
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_public_ void sd_journal_restart_data(sd_journal *j) {
|
|
|
|
|
if (!j)
|
|
|
|
|
if (!j || journal_origin_changed(j))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
j->current_field = 0;
|
|
|
|
@@ -2743,7 +2737,7 @@ _public_ int sd_journal_get_fd(sd_journal *j) {
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
|
|
|
|
|
if (j->no_inotify)
|
|
|
|
|
return -EMEDIUMTYPE;
|
|
|
|
@@ -2769,7 +2763,7 @@ _public_ int sd_journal_get_events(sd_journal *j) {
|
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
|
|
|
|
|
fd = sd_journal_get_fd(j);
|
|
|
|
|
if (fd < 0)
|
|
|
|
@@ -2782,7 +2776,7 @@ _public_ int sd_journal_get_timeout(sd_journal *j, uint64_t *timeout_usec) {
|
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
assert_return(timeout_usec, -EINVAL);
|
|
|
|
|
|
|
|
|
|
fd = sd_journal_get_fd(j);
|
|
|
|
@@ -2905,7 +2899,7 @@ _public_ int sd_journal_process(sd_journal *j) {
|
|
|
|
|
bool got_something = false;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
|
|
|
|
|
if (j->inotify_fd < 0) /* We have no inotify fd yet? Then there's noting to process. */
|
|
|
|
|
return 0;
|
|
|
|
@@ -2937,7 +2931,7 @@ _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) {
|
|
|
|
|
uint64_t t;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
|
|
|
|
|
if (j->inotify_fd < 0) {
|
|
|
|
|
JournalFile *f;
|
|
|
|
@@ -2990,7 +2984,7 @@ _public_ int sd_journal_get_cutoff_realtime_usec(sd_journal *j, uint64_t *from,
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
assert_return(from || to, -EINVAL);
|
|
|
|
|
assert_return(from != to, -EINVAL);
|
|
|
|
|
|
|
|
|
@@ -3035,7 +3029,7 @@ _public_ int sd_journal_get_cutoff_monotonic_usec(
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
assert_return(ret_from != ret_to, -EINVAL);
|
|
|
|
|
|
|
|
|
|
ORDERED_HASHMAP_FOREACH(f, j->files) {
|
|
|
|
@@ -3088,7 +3082,7 @@ _public_ int sd_journal_get_usage(sd_journal *j, uint64_t *ret) {
|
|
|
|
|
uint64_t sum = 0;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
assert_return(ret, -EINVAL);
|
|
|
|
|
|
|
|
|
|
ORDERED_HASHMAP_FOREACH(f, j->files) {
|
|
|
|
@@ -3116,7 +3110,7 @@ _public_ int sd_journal_query_unique(sd_journal *j, const char *field) {
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!isempty(field), -EINVAL);
|
|
|
|
|
assert_return(field_is_valid(field), -EINVAL);
|
|
|
|
|
|
|
|
|
@@ -3139,7 +3133,7 @@ _public_ int sd_journal_enumerate_unique(
|
|
|
|
|
size_t k;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
assert_return(j->unique_field, -EINVAL);
|
|
|
|
|
|
|
|
|
|
k = strlen(j->unique_field);
|
|
|
|
@@ -3272,7 +3266,7 @@ _public_ int sd_journal_enumerate_available_unique(sd_journal *j, const void **d
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_public_ void sd_journal_restart_unique(sd_journal *j) {
|
|
|
|
|
if (!j)
|
|
|
|
|
if (!j || journal_origin_changed(j))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
j->unique_file = NULL;
|
|
|
|
@@ -3284,7 +3278,7 @@ _public_ int sd_journal_enumerate_fields(sd_journal *j, const char **field) {
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
assert_return(field, -EINVAL);
|
|
|
|
|
|
|
|
|
|
if (!j->fields_file) {
|
|
|
|
@@ -3423,7 +3417,7 @@ _public_ int sd_journal_enumerate_fields(sd_journal *j, const char **field) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_public_ void sd_journal_restart_fields(sd_journal *j) {
|
|
|
|
|
if (!j)
|
|
|
|
|
if (!j || journal_origin_changed(j))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
j->fields_file = NULL;
|
|
|
|
@@ -3434,7 +3428,7 @@ _public_ void sd_journal_restart_fields(sd_journal *j) {
|
|
|
|
|
|
|
|
|
|
_public_ int sd_journal_reliable_fd(sd_journal *j) {
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
|
|
|
|
|
return !j->on_network;
|
|
|
|
|
}
|
|
|
|
@@ -3466,7 +3460,7 @@ _public_ int sd_journal_get_catalog(sd_journal *j, char **ret) {
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
assert_return(ret, -EINVAL);
|
|
|
|
|
|
|
|
|
|
r = sd_journal_get_data(j, "MESSAGE_ID", &data, &size);
|
|
|
|
@@ -3501,7 +3495,7 @@ _public_ int sd_journal_get_catalog_for_message_id(sd_id128_t id, char **ret) {
|
|
|
|
|
|
|
|
|
|
_public_ int sd_journal_set_data_threshold(sd_journal *j, size_t sz) {
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
|
|
|
|
|
j->data_threshold = sz;
|
|
|
|
|
return 0;
|
|
|
|
@@ -3509,7 +3503,7 @@ _public_ int sd_journal_set_data_threshold(sd_journal *j, size_t sz) {
|
|
|
|
|
|
|
|
|
|
_public_ int sd_journal_get_data_threshold(sd_journal *j, size_t *sz) {
|
|
|
|
|
assert_return(j, -EINVAL);
|
|
|
|
|
assert_return(!journal_pid_changed(j), -ECHILD);
|
|
|
|
|
assert_return(!journal_origin_changed(j), -ECHILD);
|
|
|
|
|
assert_return(sz, -EINVAL);
|
|
|
|
|
|
|
|
|
|
*sz = j->data_threshold;
|
|
|
|
|