summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/journalctl.xml32
-rw-r--r--src/journal/journalctl.c35
-rw-r--r--src/shared/util.c34
-rw-r--r--src/shared/util.h1
4 files changed, 82 insertions, 20 deletions
diff --git a/man/journalctl.xml b/man/journalctl.xml
index 66100816ae..f399868178 100644
--- a/man/journalctl.xml
+++ b/man/journalctl.xml
@@ -462,15 +462,29 @@
</varlistentry>
<varlistentry>
- <term><option>-D</option></term>
- <term><option>--directory=</option></term>
-
- <listitem><para>Takes a
- directory path as argument. If
- specified journalctl will operate on the
- specified journal directory instead of
- the default runtime and system journal
- paths.</para></listitem>
+ <term><option>-D <replaceable>DIR</replaceable></option></term>
+ <term><option>--directory=<replaceable>DIR</replaceable></option></term>
+
+ <listitem><para>Takes a directory path
+ as argument. If specified journalctl
+ will operate on the specified journal
+ directory
+ <replaceable>DIR</replaceable> instead
+ of the default runtime and system
+ journal paths.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--file=<replaceable>GLOB</replaceable></option></term>
+
+ <listitem><para>Takes a file glob as
+ argument. If specified journalctl will
+ operate on the specified journal files
+ matching <replaceable>GLOB</replaceable>
+ instead of the default runtime and
+ system journal paths. May be specified
+ multiple times, in which case files will
+ be suitably interleaved.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index af0f4ba3c8..1a441dd0d6 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -74,6 +74,7 @@ static bool arg_this_boot = false;
static bool arg_dmesg = false;
static const char *arg_cursor = NULL;
static const char *arg_directory = NULL;
+static char **arg_file = NULL;
static int arg_priorities = 0xFF;
static const char *arg_verify_key = NULL;
#ifdef HAVE_GCRYPT
@@ -130,6 +131,7 @@ static int help(void) {
" --no-pager Do not pipe output into a pager\n"
" -m --merge Show entries from all available journals\n"
" -D --directory=PATH Show journal files from directory\n"
+ " --file=PATH Show journal file\n"
" --root=ROOT Operate on catalog files underneath the root ROOT\n"
#ifdef HAVE_GCRYPT
" --interval=TIME Time interval for changing the FSS sealing key\n"
@@ -167,6 +169,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_HEADER,
ARG_FULL,
ARG_SETUP_KEYS,
+ ARG_FILE,
ARG_INTERVAL,
ARG_VERIFY,
ARG_VERIFY_KEY,
@@ -198,6 +201,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "system", no_argument, NULL, ARG_SYSTEM },
{ "user", no_argument, NULL, ARG_USER },
{ "directory", required_argument, NULL, 'D' },
+ { "file", required_argument, NULL, ARG_FILE },
{ "root", required_argument, NULL, ARG_ROOT },
{ "header", no_argument, NULL, ARG_HEADER },
{ "priority", required_argument, NULL, 'p' },
@@ -343,6 +347,14 @@ static int parse_argv(int argc, char *argv[]) {
arg_directory = optarg;
break;
+ case ARG_FILE:
+ r = glob_extend(&arg_file, optarg);
+ if (r < 0) {
+ log_error("Failed to add paths: %s", strerror(-r));
+ return r;
+ };
+ break;
+
case ARG_ROOT:
arg_root = optarg;
break;
@@ -506,6 +518,11 @@ static int parse_argv(int argc, char *argv[]) {
if (arg_follow && !arg_no_tail && arg_lines < 0)
arg_lines = 10;
+ if (arg_directory && arg_file) {
+ log_error("Please specify either -D/--directory= or --file=, not both.");
+ return -EINVAL;
+ }
+
if (arg_since_set && arg_until_set && arg_since > arg_until) {
log_error("--since= must be before --until=.");
return -EINVAL;
@@ -1110,10 +1127,14 @@ int main(int argc, char *argv[]) {
if (arg_directory)
r = sd_journal_open_directory(&j, arg_directory, arg_journal_type);
+ else if (arg_file)
+ r = sd_journal_open_files(&j, (const char**) arg_file, 0);
else
r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type);
if (r < 0) {
- log_error("Failed to open journal: %s", strerror(-r));
+ log_error("Failed to open %s: %s",
+ arg_directory ? arg_directory : arg_file ? "files" : "journal",
+ strerror(-r));
return EXIT_FAILURE;
}
@@ -1167,10 +1188,7 @@ int main(int argc, char *argv[]) {
if (r < 0)
return EXIT_FAILURE;
- /* Opening the fd now means the first sd_journal_wait() will actually wait */
- r = sd_journal_get_fd(j);
- if (r < 0)
- return EXIT_FAILURE;
+ log_debug("Journal filter: %s", j->level0 ? journal_make_match_string(j) : "none");
if (arg_field) {
const void *data;
@@ -1206,6 +1224,13 @@ int main(int argc, char *argv[]) {
return EXIT_SUCCESS;
}
+ /* Opening the fd now means the first sd_journal_wait() will actually wait */
+ if (arg_follow) {
+ r = sd_journal_get_fd(j);
+ if (r < 0)
+ return EXIT_FAILURE;
+ }
+
if (arg_cursor) {
r = sd_journal_seek_cursor(j, arg_cursor);
if (r < 0) {
diff --git a/src/shared/util.c b/src/shared/util.c
index 17928ec36e..04811ff26b 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -4353,7 +4353,7 @@ int in_group(const char *name) {
int glob_exists(const char *path) {
_cleanup_globfree_ glob_t g = {};
- int r, k;
+ int k;
assert(path);
@@ -4361,15 +4361,37 @@ int glob_exists(const char *path) {
k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
if (k == GLOB_NOMATCH)
- r = 0;
+ return 0;
else if (k == GLOB_NOSPACE)
- r = -ENOMEM;
+ return -ENOMEM;
else if (k == 0)
- r = !strv_isempty(g.gl_pathv);
+ return !strv_isempty(g.gl_pathv);
else
- r = errno ? -errno : -EIO;
+ return errno ? -errno : -EIO;
+}
- return r;
+int glob_extend(char ***strv, const char *path) {
+ _cleanup_globfree_ glob_t g = {};
+ int k;
+ char **p;
+
+ errno = 0;
+ k = glob(optarg, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
+
+ if (k == GLOB_NOMATCH)
+ return -ENOENT;
+ else if (k == GLOB_NOSPACE)
+ return -ENOMEM;
+ else if (k != 0 || strv_isempty(g.gl_pathv))
+ return errno ? -errno : -EIO;
+
+ STRV_FOREACH(p, g.gl_pathv) {
+ k = strv_extend(strv, *p);
+ if (k < 0)
+ break;
+ }
+
+ return k;
}
int dirent_ensure_type(DIR *d, struct dirent *de) {
diff --git a/src/shared/util.h b/src/shared/util.h
index e6f9312e95..ddb21b4a9c 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -439,6 +439,7 @@ char* uid_to_name(uid_t uid);
char* gid_to_name(gid_t gid);
int glob_exists(const char *path);
+int glob_extend(char ***strv, const char *path);
int dirent_ensure_type(DIR *d, struct dirent *de);