From 32485d09046d36fed436a1eaefbf0fac5bfc9a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Giedrius=20Statkevi=C4=8Dius?= Date: Fri, 24 Feb 2017 21:29:40 +0200 Subject: [PATCH 1/3] 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. --- src/coredump/coredumpctl.c | 80 ++++++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 12 deletions(-) diff --git a/src/coredump/coredumpctl.c b/src/coredump/coredumpctl.c index 43dba82c3a6..4ac98d8163d 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) { From 4ab2753e368e0872fce7835650688af12d26920f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Giedrius=20Statkevi=C4=8Dius?= Date: Fri, 24 Feb 2017 21:30:41 +0200 Subject: [PATCH 2/3] man/coredumpctl: document the new options -S/-U --- man/coredumpctl.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/man/coredumpctl.xml b/man/coredumpctl.xml index 72a244d2eb0..5204db40730 100644 --- a/man/coredumpctl.xml +++ b/man/coredumpctl.xml @@ -91,6 +91,20 @@ all known core dumps. + + + + + Only print entries which are since the specified date. + + + + + + + Only print entries which are until the specified date. + + From 15710d44791f8f56dd688cff6c597622bbd70b3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Giedrius=20Statkevi=C4=8Dius?= Date: Fri, 24 Feb 2017 21:30:59 +0200 Subject: [PATCH 3/3] shell-completion: include the new coredumpctl options --- shell-completion/bash/coredumpctl | 2 +- shell-completion/zsh/_coredumpctl | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/shell-completion/bash/coredumpctl b/shell-completion/bash/coredumpctl index d34f89e2bb9..87fe473e091 100644 --- a/shell-completion/bash/coredumpctl +++ b/shell-completion/bash/coredumpctl @@ -38,7 +38,7 @@ _coredumpctl() { local i verb comps local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} local OPTS='-h --help --version --no-pager --no-legend -o --output -F --field -1 - -r --reverse' + -r --reverse -S --since -U --until' local -A VERBS=( [LIST]='list' diff --git a/shell-completion/zsh/_coredumpctl b/shell-completion/zsh/_coredumpctl index 64b44c1214c..e469bca9582 100644 --- a/shell-completion/zsh/_coredumpctl +++ b/shell-completion/zsh/_coredumpctl @@ -32,6 +32,8 @@ _arguments \ {-o+,--output=}'[Write output to FILE]:output file:_files' \ {-F+,--field=}'[Show field in list output]:field' \ '-1[Show information about most recent entry only]' \ + {-S,--since}'[Print entries since the specified date]' \ + {-U,--until}'[Print entries until the specified date]' \ {-r,--reverse}'[Show the newest entries first]' \ '--no-pager[Do not pipe output into a pager]' \ '--no-legend[Do not print the column headers]' \