diff options
-rw-r--r-- | man/journalctl.xml | 32 | ||||
-rw-r--r-- | src/journal/journalctl.c | 35 | ||||
-rw-r--r-- | src/shared/util.c | 34 | ||||
-rw-r--r-- | src/shared/util.h | 1 |
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); |