diff options
author | Giedrius Statkevičius <giedrius.statkevicius@gmail.com> | 2017-02-24 21:29:40 +0200 |
---|---|---|
committer | Giedrius Statkevičius <giedrius.statkevicius@gmail.com> | 2017-02-24 21:29:40 +0200 |
commit | 32485d09046d36fed436a1eaefbf0fac5bfc9a47 (patch) | |
tree | 51b430a6e15d30113f67db8d2ebb7f82bfc6b3f1 /src/coredump | |
parent | 00f331c14121cd572365e49b04001a29715f56dd (diff) |
coredumpctl: implement --since/--until (-S/-U) for info/list verbs
Implement --since/--until (-S/-U) in the same fashion as journalctl.
This lets the user filter the results a bit so it would be easier to
find relevant info in case there were many core dumps.
Diffstat (limited to 'src/coredump')
-rw-r--r-- | src/coredump/coredumpctl.c | 80 |
1 files changed, 68 insertions, 12 deletions
diff --git a/src/coredump/coredumpctl.c b/src/coredump/coredumpctl.c index 43dba82c3a..4ac98d8163 100644 --- a/src/coredump/coredumpctl.c +++ b/src/coredump/coredumpctl.c @@ -50,6 +50,8 @@ #include "user-util.h" #include "util.h" +static usec_t arg_since = USEC_INFINITY, arg_until = USEC_INFINITY; + static enum { ACTION_NONE, ACTION_INFO, @@ -128,11 +130,12 @@ static void help(void) { " --no-pager Do not pipe output into a pager\n" " --no-legend Do not print the column headers.\n" " -1 Show information about most recent entry only\n" + " -S --since=DATE Only print coredumps since the date\n" + " -U --until=DATE Only print coredumps until the date\n" " -r --reverse Show the newest entries first\n" " -F --field=FIELD List all values a certain field takes\n" " -o --output=FILE Write output to FILE\n" " -D --directory=DIR Use journal files from directory\n\n" - "Commands:\n" " list [MATCHES...] List available coredumps (default)\n" " info [MATCHES...] Show detailed information about one or more coredumps\n" @@ -148,7 +151,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_NO_LEGEND, }; - int c; + int c, r; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, @@ -159,15 +162,16 @@ static int parse_argv(int argc, char *argv[]) { { "field", required_argument, NULL, 'F' }, { "directory", required_argument, NULL, 'D' }, { "reverse", no_argument, NULL, 'r' }, + { "since", required_argument, NULL, 'S' }, + { "until", required_argument, NULL, 'U' }, {} }; assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "ho:F:1D:r", options, NULL)) >= 0) + while ((c = getopt_long(argc, argv, "ho:F:1D:S:U:r", options, NULL)) >= 0) switch(c) { - case 'h': arg_action = ACTION_NONE; help(); @@ -197,6 +201,18 @@ static int parse_argv(int argc, char *argv[]) { break; + case 'S': + r = parse_timestamp(optarg, &arg_since); + if (r < 0) + return log_error_errno(r, "Failed to parse timestamp: %s", optarg); + break; + + case 'U': + r = parse_timestamp(optarg, &arg_until); + if (r < 0) + return log_error_errno(r, "Failed to parse timestamp: %s", optarg); + break; + case 'F': if (arg_field) { log_error("cannot use --field/-F more than once"); @@ -224,6 +240,12 @@ static int parse_argv(int argc, char *argv[]) { assert_not_reached("Unhandled option"); } + if (arg_since != USEC_INFINITY && arg_until != USEC_INFINITY && + arg_since > arg_until) { + log_error("--since= must be before --until=."); + return -EINVAL; + } + if (optind < argc) { const char *cmd = argv[optind++]; if (streq(cmd, "list")) @@ -610,18 +632,52 @@ static int dump_list(sd_journal *j) { return print_entry(j, 0); } else { - if (!arg_reverse) { - SD_JOURNAL_FOREACH(j) { - r = print_entry(j, n_found++); + if (arg_since != USEC_INFINITY && !arg_reverse) + r = sd_journal_seek_realtime_usec(j, arg_since); + else if (arg_until != USEC_INFINITY && arg_reverse) + r = sd_journal_seek_realtime_usec(j, arg_until); + else if (arg_reverse) + r = sd_journal_seek_tail(j); + else + r = sd_journal_seek_head(j); + if (r < 0) + return log_error_errno(r, "Failed to seek to date: %m"); + + for (;;) { + if (!arg_reverse) + r = sd_journal_next(j); + else + r = sd_journal_previous(j); + + if (r < 0) + return log_error_errno(r, "Failed to iterate through journal: %m"); + + if (r == 0) + break; + + if (arg_until != USEC_INFINITY && !arg_reverse) { + usec_t usec; + + r = sd_journal_get_realtime_usec(j, &usec); if (r < 0) - return r; + return log_error_errno(r, "Failed to determine timestamp: %m"); + if (usec > arg_until) + continue; } - } else { - SD_JOURNAL_FOREACH_BACKWARDS(j) { - r = print_entry(j, n_found++); + + if (arg_since != USEC_INFINITY && arg_reverse) { + usec_t usec; + + r = sd_journal_get_realtime_usec(j, &usec); if (r < 0) - return r; + return log_error_errno(r, "Failed to determine timestamp: %m"); + if (usec < arg_since) + continue; } + + r = print_entry(j, n_found++); + if (r < 0) + return r; } if (!arg_field && n_found <= 0) { |