summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile-man.am5
-rw-r--r--man/sd_journal_open.xml23
-rw-r--r--src/journal/journal-internal.h1
-rw-r--r--src/journal/libsystemd-journal.sym5
-rw-r--r--src/journal/sd-journal.c117
-rw-r--r--src/systemd/sd-journal.h1
6 files changed, 130 insertions, 22 deletions
diff --git a/Makefile-man.am b/Makefile-man.am
index a31427e9b9..807ad783fb 100644
--- a/Makefile-man.am
+++ b/Makefile-man.am
@@ -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)
diff --git a/man/sd_journal_open.xml b/man/sd_journal_open.xml
index dd2f32d81a..4ac94c4ce3 100644
--- a/man/sd_journal_open.xml
+++ b/man/sd_journal_open.xml
@@ -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>
@@ -72,6 +73,13 @@
</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>
</funcprototype>
@@ -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>
diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h
index f576a0073d..5b717f86f7 100644
--- a/src/journal/journal-internal.h
+++ b/src/journal/journal-internal.h
@@ -123,6 +123,7 @@ struct sd_journal {
uint64_t unique_offset;
bool on_network;
+ bool no_new_files;
size_t data_threshold;
diff --git a/src/journal/libsystemd-journal.sym b/src/journal/libsystemd-journal.sym
index 449f37c4da..4eb15910d2 100644
--- a/src/journal/libsystemd-journal.sym
+++ b/src/journal/libsystemd-journal.sym
@@ -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;
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 8986763e4d..3aa9ed4b32 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -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);
diff --git a/src/systemd/sd-journal.h b/src/systemd/sd-journal.h
index cf105cde72..72ea328b28 100644
--- a/src/systemd/sd-journal.h
+++ b/src/systemd/sd-journal.h
@@ -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);