mirror of
https://github.com/systemd/systemd.git
synced 2025-01-13 17:18:18 +03:00
journal: add sd_journal_open_files
This allows the caller to explicitly specify which journal files should be opened. The same functionality could be achieved before by creating a directory and playing around with symlinks. It is useful to debug stuff and explore the journal, and has been requested before. Waiting is supported, the journal will notice modifications on the files supplied when opening the journal, but will not add any new files.
This commit is contained in:
parent
6eb7a9a001
commit
5302ebe15f
@ -148,6 +148,7 @@ MANPAGES_ALIAS += \
|
||||
man/sd_journal_get_timeout.3 \
|
||||
man/sd_journal_next_skip.3 \
|
||||
man/sd_journal_open_directory.3 \
|
||||
man/sd_journal_open_files.3 \
|
||||
man/sd_journal_perror.3 \
|
||||
man/sd_journal_previous.3 \
|
||||
man/sd_journal_previous_skip.3 \
|
||||
@ -248,6 +249,7 @@ man/sd_journal_get_monotonic_usec.3: man/sd_journal_get_realtime_usec.3
|
||||
man/sd_journal_get_timeout.3: man/sd_journal_get_fd.3
|
||||
man/sd_journal_next_skip.3: man/sd_journal_next.3
|
||||
man/sd_journal_open_directory.3: man/sd_journal_open.3
|
||||
man/sd_journal_open_files.3: man/sd_journal_open.3
|
||||
man/sd_journal_perror.3: man/sd_journal_print.3
|
||||
man/sd_journal_previous.3: man/sd_journal_next.3
|
||||
man/sd_journal_previous_skip.3: man/sd_journal_next.3
|
||||
@ -452,6 +454,9 @@ man/sd_journal_next_skip.html: man/sd_journal_next.html
|
||||
man/sd_journal_open_directory.html: man/sd_journal_open.html
|
||||
$(html-alias)
|
||||
|
||||
man/sd_journal_open_files.html: man/sd_journal_open.html
|
||||
$(html-alias)
|
||||
|
||||
man/sd_journal_perror.html: man/sd_journal_print.html
|
||||
$(html-alias)
|
||||
|
||||
|
@ -45,6 +45,7 @@
|
||||
<refnamediv>
|
||||
<refname>sd_journal_open</refname>
|
||||
<refname>sd_journal_open_directory</refname>
|
||||
<refname>sd_journal_open_files</refname>
|
||||
<refname>sd_journal_close</refname>
|
||||
<refname>sd_journal</refname>
|
||||
<refname>SD_JOURNAL_LOCAL_ONLY</refname>
|
||||
@ -71,6 +72,13 @@
|
||||
<paramdef>int <parameter>flags</parameter></paramdef>
|
||||
</funcprototype>
|
||||
|
||||
<funcprototype>
|
||||
<funcdef>int <function>sd_journal_open_files</function></funcdef>
|
||||
<paramdef>sd_journal** <parameter>ret</parameter></paramdef>
|
||||
<paramdef>const char** <parameter>paths</parameter></paramdef>
|
||||
<paramdef>int <parameter>flags</parameter></paramdef>
|
||||
</funcprototype>
|
||||
|
||||
<funcprototype>
|
||||
<funcdef>void <function>sd_journal_close</function></funcdef>
|
||||
<paramdef>sd_journal* <parameter>j</parameter></paramdef>
|
||||
@ -111,6 +119,14 @@
|
||||
flags argument, but it must be passed as 0 as no flags
|
||||
are currently understood for this call.</para>
|
||||
|
||||
<para><function>sd_journal_open_files()</function>
|
||||
is similar to <function>sd_journal_open()</function>
|
||||
but takes a <literal>NULL</literal>-terminated list
|
||||
of file paths to open. All files will be opened and
|
||||
interleaved automatically. This call also takes a
|
||||
flags argument, but it must be passed as 0 as no flags
|
||||
are currently understood for this call.</para>
|
||||
|
||||
<para><function>sd_journal_close()</function> will
|
||||
close the journal context allocated with
|
||||
<function>sd_journal_open()</function> or
|
||||
@ -188,9 +204,10 @@
|
||||
<para><function>sd_journal_open_directory()</function>
|
||||
was added in systemd-187.</para>
|
||||
|
||||
<para><literal>SD_JOURNAL_SYSTEM</literal> and
|
||||
<literal>SD_JOURNAL_CURRENT_USER</literal> were added
|
||||
in systemd-205.
|
||||
<para><literal>SD_JOURNAL_SYSTEM</literal>,
|
||||
<literal>SD_JOURNAL_CURRENT_USER</literal>,
|
||||
and <function>sd_journal_open_files()</function>
|
||||
were added in systemd-205.
|
||||
<literal>SD_JOURNAL_SYSTEM_ONLY</literal>
|
||||
was deprecated.</para>
|
||||
</refsect1>
|
||||
|
@ -123,6 +123,7 @@ struct sd_journal {
|
||||
uint64_t unique_offset;
|
||||
|
||||
bool on_network;
|
||||
bool no_new_files;
|
||||
|
||||
size_t data_threshold;
|
||||
|
||||
|
@ -104,3 +104,8 @@ LIBSYSTEMD_JOURNAL_202 {
|
||||
global:
|
||||
sd_journal_add_conjunction;
|
||||
} LIBSYSTEMD_JOURNAL_201;
|
||||
|
||||
LIBSYSTEMD_JOURNAL_205 {
|
||||
global:
|
||||
sd_journal_open_files;
|
||||
} LIBSYSTEMD_JOURNAL_202;
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "journal-file.h"
|
||||
#include "hashmap.h"
|
||||
#include "list.h"
|
||||
#include "strv.h"
|
||||
#include "path-util.h"
|
||||
#include "lookup3.h"
|
||||
#include "compress.h"
|
||||
@ -1278,37 +1279,24 @@ static bool file_type_wanted(int flags, const char *filename) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static int add_file(sd_journal *j, const char *prefix, const char *filename) {
|
||||
_cleanup_free_ char *path = NULL;
|
||||
int r;
|
||||
static int add_any_file(sd_journal *j, const char *path) {
|
||||
JournalFile *f;
|
||||
int r;
|
||||
|
||||
assert(j);
|
||||
assert(prefix);
|
||||
assert(filename);
|
||||
|
||||
if (!file_type_wanted(j->flags, filename))
|
||||
return 0;
|
||||
|
||||
path = strjoin(prefix, "/", filename, NULL);
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
assert(path);
|
||||
|
||||
if (hashmap_get(j->files, path))
|
||||
return 0;
|
||||
|
||||
if (hashmap_size(j->files) >= JOURNAL_FILES_MAX) {
|
||||
log_debug("Too many open journal files, not adding %s, ignoring.", path);
|
||||
log_warning("Too many open journal files, not adding %s.", path);
|
||||
return set_put_error(j, -ETOOMANYREFS);
|
||||
}
|
||||
|
||||
r = journal_file_open(path, O_RDONLY, 0, false, false, NULL, j->mmap, NULL, &f);
|
||||
if (r < 0) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* journal_file_dump(f); */
|
||||
|
||||
@ -1327,6 +1315,28 @@ static int add_file(sd_journal *j, const char *prefix, const char *filename) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_file(sd_journal *j, const char *prefix, const char *filename) {
|
||||
_cleanup_free_ char *path = NULL;
|
||||
int r;
|
||||
|
||||
assert(j);
|
||||
assert(prefix);
|
||||
assert(filename);
|
||||
|
||||
if (j->no_new_files ||
|
||||
!file_type_wanted(j->flags, filename))
|
||||
return 0;
|
||||
|
||||
path = strjoin(prefix, "/", filename, NULL);
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
|
||||
r = add_any_file(j, path);
|
||||
if (r == -ENOENT)
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int remove_file(sd_journal *j, const char *prefix, const char *filename) {
|
||||
char *path;
|
||||
JournalFile *f;
|
||||
@ -1507,6 +1517,9 @@ static int add_root_directory(sd_journal *j, const char *p) {
|
||||
inotify_rm_watch(j->inotify_fd, m->wd);
|
||||
}
|
||||
|
||||
if (j->no_new_files)
|
||||
return 0;
|
||||
|
||||
for (;;) {
|
||||
struct dirent *de;
|
||||
union dirent_storage buf;
|
||||
@ -1587,6 +1600,36 @@ static int add_search_paths(sd_journal *j) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_current_paths(sd_journal *j) {
|
||||
Iterator i;
|
||||
JournalFile *f;
|
||||
|
||||
assert(j);
|
||||
assert(j->no_new_files);
|
||||
|
||||
/* Simply adds all directories for files we have open as
|
||||
* "root" directories. We don't expect errors here, so we
|
||||
* treat them as fatal. */
|
||||
|
||||
HASHMAP_FOREACH(f, j->files, i) {
|
||||
int r;
|
||||
_cleanup_free_ char *dir;
|
||||
|
||||
dir = dirname_malloc(f->path);
|
||||
if (!dir)
|
||||
return -ENOMEM;
|
||||
|
||||
r = add_root_directory(j, dir);
|
||||
if (r < 0) {
|
||||
set_put_error(j, r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int allocate_inotify(sd_journal *j) {
|
||||
assert(j);
|
||||
|
||||
@ -1697,6 +1740,40 @@ fail:
|
||||
return r;
|
||||
}
|
||||
|
||||
_public_ int sd_journal_open_files(sd_journal **ret, const char **paths, int flags) {
|
||||
sd_journal *j;
|
||||
const char **path;
|
||||
int r;
|
||||
|
||||
if (!ret)
|
||||
return -EINVAL;
|
||||
|
||||
if (flags != 0)
|
||||
return -EINVAL;
|
||||
|
||||
j = journal_new(flags, NULL);
|
||||
if (!j)
|
||||
return -ENOMEM;
|
||||
|
||||
STRV_FOREACH(path, paths) {
|
||||
r = add_any_file(j, *path);
|
||||
if (r < 0) {
|
||||
log_error("Failed to open %s: %s", *path, strerror(-r));
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
j->no_new_files = true;
|
||||
|
||||
*ret = j;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
sd_journal_close(j);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
_public_ void sd_journal_close(sd_journal *j) {
|
||||
Directory *d;
|
||||
JournalFile *f;
|
||||
@ -2017,7 +2094,9 @@ _public_ int sd_journal_get_fd(sd_journal *j) {
|
||||
|
||||
/* Iterate through all dirs again, to add them to the
|
||||
* inotify */
|
||||
if (j->path)
|
||||
if (j->no_new_files)
|
||||
r = add_current_paths(j);
|
||||
else if (j->path)
|
||||
r = add_root_directory(j, j->path);
|
||||
else
|
||||
r = add_search_paths(j);
|
||||
|
@ -100,6 +100,7 @@ enum {
|
||||
|
||||
int sd_journal_open(sd_journal **ret, int flags);
|
||||
int sd_journal_open_directory(sd_journal **ret, const char *path, int flags);
|
||||
int sd_journal_open_files(sd_journal **ret, const char **paths, int flags);
|
||||
void sd_journal_close(sd_journal *j);
|
||||
|
||||
int sd_journal_previous(sd_journal *j);
|
||||
|
Loading…
x
Reference in New Issue
Block a user