summaryrefslogtreecommitdiff
path: root/src/grp-journal/journalctl
diff options
context:
space:
mode:
Diffstat (limited to 'src/grp-journal/journalctl')
-rw-r--r--src/grp-journal/journalctl/Makefile2
-rw-r--r--src/grp-journal/journalctl/journalctl.c61
-rw-r--r--src/grp-journal/journalctl/journalctl.completion.bash16
-rw-r--r--src/grp-journal/journalctl/journalctl.xml34
4 files changed, 63 insertions, 50 deletions
diff --git a/src/grp-journal/journalctl/Makefile b/src/grp-journal/journalctl/Makefile
index 3c98169647..bf5a4d3924 100644
--- a/src/grp-journal/journalctl/Makefile
+++ b/src/grp-journal/journalctl/Makefile
@@ -31,7 +31,7 @@ journalctl_SOURCES = \
src/journal/journalctl.c
journalctl_LDADD = \
- libshared.la \
+ libsystemd-shared.la \
libudev-core.la
ifneq ($(HAVE_QRENCODE),)
diff --git a/src/grp-journal/journalctl/journalctl.c b/src/grp-journal/journalctl/journalctl.c
index 8901b46ae5..e50c21d681 100644
--- a/src/grp-journal/journalctl/journalctl.c
+++ b/src/grp-journal/journalctl/journalctl.c
@@ -350,6 +350,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_NO_FULL,
ARG_NO_TAIL,
ARG_NEW_ID128,
+ ARG_THIS_BOOT,
ARG_LIST_BOOTS,
ARG_USER,
ARG_SYSTEM,
@@ -394,9 +395,9 @@ static int parse_argv(int argc, char *argv[]) {
{ "new-id128", no_argument, NULL, ARG_NEW_ID128 },
{ "quiet", no_argument, NULL, 'q' },
{ "merge", no_argument, NULL, 'm' },
+ { "this-boot", no_argument, NULL, ARG_THIS_BOOT }, /* deprecated */
{ "boot", optional_argument, NULL, 'b' },
{ "list-boots", no_argument, NULL, ARG_LIST_BOOTS },
- { "this-boot", optional_argument, NULL, 'b' }, /* deprecated */
{ "dmesg", no_argument, NULL, 'k' },
{ "system", no_argument, NULL, ARG_SYSTEM },
{ "user", no_argument, NULL, ARG_USER },
@@ -546,6 +547,10 @@ static int parse_argv(int argc, char *argv[]) {
arg_merge = true;
break;
+ case ARG_THIS_BOOT:
+ arg_boot = true;
+ break;
+
case 'b':
arg_boot = true;
@@ -870,8 +875,8 @@ static int parse_argv(int argc, char *argv[]) {
return -EINVAL;
}
- if ((arg_boot || arg_action == ACTION_LIST_BOOTS) && (arg_file || arg_directory || arg_merge)) {
- log_error("Using --boot or --list-boots with --file, --directory or --merge is not supported.");
+ if ((arg_boot || arg_action == ACTION_LIST_BOOTS) && arg_merge) {
+ log_error("Using --boot or --list-boots with --merge is not supported.");
return -EINVAL;
}
@@ -1104,13 +1109,13 @@ static int discover_next_boot(sd_journal *j,
static int get_boots(
sd_journal *j,
BootId **boots,
- sd_id128_t *query_ref_boot,
- int ref_boot_offset) {
+ sd_id128_t *boot_id,
+ int offset) {
bool skip_once;
int r, count = 0;
BootId *head = NULL, *tail = NULL;
- const bool advance_older = query_ref_boot && ref_boot_offset <= 0;
+ const bool advance_older = boot_id && offset <= 0;
sd_id128_t previous_boot_id;
assert(j);
@@ -1118,19 +1123,19 @@ static int get_boots(
/* Adjust for the asymmetry that offset 0 is
* the last (and current) boot, while 1 is considered the
* (chronological) first boot in the journal. */
- skip_once = query_ref_boot && sd_id128_is_null(*query_ref_boot) && ref_boot_offset < 0;
+ skip_once = boot_id && sd_id128_is_null(*boot_id) && offset <= 0;
/* Advance to the earliest/latest occurrence of our reference
* boot ID (taking our lookup direction into account), so that
* discover_next_boot() can do its job.
* If no reference is given, the journal head/tail will do,
* they're "virtual" boots after all. */
- if (query_ref_boot && !sd_id128_is_null(*query_ref_boot)) {
+ if (boot_id && !sd_id128_is_null(*boot_id)) {
char match[9+32+1] = "_BOOT_ID=";
sd_journal_flush_matches(j);
- sd_id128_to_string(*query_ref_boot, match + 9);
+ sd_id128_to_string(*boot_id, match + 9);
r = sd_journal_add_match(j, match, sizeof(match) - 1);
if (r < 0)
return r;
@@ -1150,7 +1155,7 @@ static int get_boots(
return r;
else if (r == 0)
goto finish;
- else if (ref_boot_offset == 0) {
+ else if (offset == 0) {
count = 1;
goto finish;
}
@@ -1189,14 +1194,14 @@ static int get_boots(
previous_boot_id = current->id;
- if (query_ref_boot) {
+ if (boot_id) {
if (!skip_once)
- ref_boot_offset += advance_older ? 1 : -1;
+ offset += advance_older ? 1 : -1;
skip_once = false;
- if (ref_boot_offset == 0) {
+ if (offset == 0) {
count = 1;
- *query_ref_boot = current->id;
+ *boot_id = current->id;
break;
}
} else {
@@ -1252,7 +1257,7 @@ static int list_boots(sd_journal *j) {
static int add_boot(sd_journal *j) {
char match[9+32+1] = "_BOOT_ID=";
- sd_id128_t ref_boot_id;
+ sd_id128_t boot_id;
int r;
assert(j);
@@ -1260,11 +1265,16 @@ static int add_boot(sd_journal *j) {
if (!arg_boot)
return 0;
- if (arg_boot_offset == 0 && sd_id128_equal(arg_boot_id, SD_ID128_NULL))
+ /* Take a shortcut and use the current boot_id, which we can do very quickly.
+ * We can do this only when we logs are coming from the current machine,
+ * so take the slow path if log location is specified. */
+ if (arg_boot_offset == 0 && sd_id128_is_null(arg_boot_id) &&
+ !arg_directory && !arg_file)
+
return add_match_this_boot(j, arg_machine);
- ref_boot_id = arg_boot_id;
- r = get_boots(j, NULL, &ref_boot_id, arg_boot_offset);
+ boot_id = arg_boot_id;
+ r = get_boots(j, NULL, &boot_id, arg_boot_offset);
assert(r <= 1);
if (r <= 0) {
const char *reason = (r == 0) ? "No such boot ID in journal" : strerror(-r);
@@ -1279,7 +1289,7 @@ static int add_boot(sd_journal *j) {
return r == 0 ? -ENODATA : r;
}
- sd_id128_to_string(ref_boot_id, match + 9);
+ sd_id128_to_string(boot_id, match + 9);
r = sd_journal_add_match(j, match, sizeof(match) - 1);
if (r < 0)
@@ -1666,15 +1676,19 @@ static int setup_keys(void) {
if (on_tty()) {
fprintf(stderr,
"\n"
- "The new key pair has been generated. The " ANSI_HIGHLIGHT "secret sealing key" ANSI_NORMAL " has been written to\n"
+ "The new key pair has been generated. The %ssecret sealing key%s has been written to\n"
"the following local file. This key file is automatically updated when the\n"
"sealing key is advanced. It should not be used on multiple hosts.\n"
"\n"
"\t%s\n"
"\n"
- "Please write down the following " ANSI_HIGHLIGHT "secret verification key" ANSI_NORMAL ". It should be stored\n"
+ "Please write down the following %ssecret verification key%s. It should be stored\n"
"at a safe location and should not be saved locally on disk.\n"
- "\n\t" ANSI_HIGHLIGHT_RED, p);
+ "\n\t%s",
+ ansi_highlight(), ansi_normal(),
+ ansi_highlight(), ansi_normal(),
+ ansi_highlight_red(),
+ p);
fflush(stderr);
}
for (i = 0; i < seed_size; i++) {
@@ -1689,8 +1703,9 @@ static int setup_keys(void) {
char tsb[FORMAT_TIMESPAN_MAX], *hn;
fprintf(stderr,
- ANSI_NORMAL "\n"
+ "%s\n"
"The sealing key is automatically changed every %s.\n",
+ ansi_normal(),
format_timespan(tsb, sizeof(tsb), arg_interval, 0));
hn = gethostname_malloc();
diff --git a/src/grp-journal/journalctl/journalctl.completion.bash b/src/grp-journal/journalctl/journalctl.completion.bash
index 7c8a9ce361..53bedcd92e 100644
--- a/src/grp-journal/journalctl/journalctl.completion.bash
+++ b/src/grp-journal/journalctl/journalctl.completion.bash
@@ -30,17 +30,6 @@ __get_machines() {
{ while read a b; do echo " $a"; done; } | sort -u;
}
-__journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC}
- ERRNO SYSLOG_{FACILITY,IDENTIFIER,PID} COREDUMP_EXE
- _{P,U,G}ID _COMM _EXE _CMDLINE
- _CAP_EFFECTIVE _AUDIT_{SESSION,LOGINUID}
- _SYSTEMD_{CGROUP,SESSION,{,USER_}UNIT,OWNER_UID,SLICE}
- _SELINUX_CONTEXT _SOURCE_REALTIME_TIMESTAMP
- _{BOOT,MACHINE}_ID _HOSTNAME _TRANSPORT
- _KERNEL_{DEVICE,SUBSYSTEM}
- _UDEV_{SYSNAME,DEVNODE,DEVLINK}
- __CURSOR __{REALTIME,MONOTONIC}_TIMESTAMP)
-
__syslog_priorities=(emerg alert crit err warning notice info debug)
_journalctl() {
@@ -79,7 +68,7 @@ _journalctl() {
comps='short short-iso short-precise short-monotonic verbose export json json-pretty json-sse cat'
;;
--field|-F)
- comps=${__journal_fields[*]}
+ comps=$(journalctl --fields | sort 2>/dev/null)
;;
--machine|-M)
comps=$( __get_machines )
@@ -125,8 +114,9 @@ _journalctl() {
mapfile -t field_vals < <(journalctl -F "${COMP_WORDS[COMP_CWORD-2]}" 2>/dev/null)
COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "$cur") )
else
+ mapfile -t field_vals < <(journalctl --fields 2>/dev/null)
compopt -o nospace
- COMPREPLY=( $(compgen -W '${__journal_fields[*]}' -S= -- "$cur") )
+ COMPREPLY=( $(compgen -W '${field_vals[*]}' -S= -- "$cur") )
fi
}
diff --git a/src/grp-journal/journalctl/journalctl.xml b/src/grp-journal/journalctl/journalctl.xml
index 3efe6ef62a..e77621d7b3 100644
--- a/src/grp-journal/journalctl/journalctl.xml
+++ b/src/grp-journal/journalctl/journalctl.xml
@@ -87,18 +87,26 @@
causes all matches before and after to be combined in a
disjunction (i.e. logical OR).</para>
- <para>As shortcuts for a few types of field/value matches, file
- paths may be specified. If a file path refers to an executable
- file, this is equivalent to an <literal>_EXE=</literal> match
- for the canonicalized binary path. Similarly, if a path refers
- to a device node then match is added for the kernel name of the
- device (<literal>_KERNEL_DEVICE=</literal>). Also, matches for the
- kernel names of all the parent devices are added automatically.
- Device node paths are not stable across reboots, therefore match
- for the current boot id (<literal>_BOOT_ID=</literal>) is
- always added as well. Note that only the log entries for
- the existing device nodes maybe queried by providing path to
- the device node.</para>
+ <para>It is also possible to filter the entries by specifying an
+ absolute file path as an argument. The file path may be a file or
+ a symbolic link and the file must exist at the time of the query. If a
+ file path refers to an executable binary, an <literal>_EXE=</literal>
+ match for the canonicalized binary path is added to the query. If a
+ file path refers to an executable script, a <literal>_COMM=</literal>
+ match for the script name is added to the query. If a file path
+ refers to a device node, <literal>_KERNEL_DEVICE=</literal> matches for
+ the kernel name of the device and for each of its ancestor devices is
+ added to the query. Symbolic links are dereferenced, kernel names are
+ synthesized, and parent devices are identified from the environment at
+ the time of the query. In general, a device node is the best proxy for
+ an actual device, as log entries do not usually contain fields that
+ identify an actual device. For the resulting log entries to be correct
+ for the actual device, the relevant parts of the environment at the time
+ the entry was logged, in particular the actual device corresponding to
+ the device node, must have been the same as those at the time of the
+ query. Because device nodes generally change their corresponding devices
+ across reboots, specifying a device node path causes the resulting
+ entries to be restricted to those from the current boot.</para>
<para>Additional constraints may be added using options
<option>--boot</option>, <option>--unit=</option>, etc., to
@@ -824,7 +832,7 @@
flushed from <filename>/run/log/journal</filename> into
<filename>/var/log/journal</filename> once during system
runtime, and this command exits cleanly without executing any
- operation if this has already has happened. This command
+ operation if this has already happened. This command
effectively guarantees that all data is flushed to
<filename>/var/log/journal</filename> at the time it
returns.</para></listitem>