1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
12 #include <sys/inotify.h>
17 #include "sd-device.h"
18 #include "sd-journal.h"
21 #include "alloc-util.h"
23 #include "bus-error.h"
24 #include "bus-locator.h"
28 #include "chattr-util.h"
29 #include "constants.h"
30 #include "devnum-util.h"
31 #include "dissect-image.h"
34 #include "format-table.h"
35 #include "format-util.h"
38 #include "glob-util.h"
39 #include "hostname-util.h"
40 #include "id128-print.h"
42 #include "journal-def.h"
43 #include "journal-internal.h"
44 #include "journal-util.h"
45 #include "journal-vacuum.h"
46 #include "journal-verify.h"
47 #include "locale-util.h"
49 #include "logs-show.h"
50 #include "main-func.h"
51 #include "memory-util.h"
52 #include "memstream-util.h"
53 #include "missing_sched.h"
55 #include "mount-util.h"
56 #include "mountpoint-util.h"
57 #include "nulstr-util.h"
59 #include "parse-argument.h"
60 #include "parse-util.h"
61 #include "path-util.h"
62 #include "pcre2-util.h"
63 #include "pretty-print.h"
64 #include "qrcode-util.h"
65 #include "random-util.h"
66 #include "rlimit-util.h"
69 #include "signal-util.h"
70 #include "static-destruct.h"
71 #include "stdio-util.h"
72 #include "string-table.h"
74 #include "syslog-util.h"
75 #include "terminal-util.h"
76 #include "tmpfile-util.h"
77 #include "unit-name.h"
78 #include "user-util.h"
81 #define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
82 #define PROCESS_INOTIFY_INTERVAL 1024 /* Every 1,024 messages processed */
85 /* Special values for arg_lines */
86 ARG_LINES_DEFAULT
= -2,
90 static OutputMode arg_output
= OUTPUT_SHORT
;
91 static JsonFormatFlags arg_json_format_flags
= JSON_FORMAT_OFF
;
92 static bool arg_utc
= false;
93 static bool arg_follow
= false;
94 static bool arg_full
= true;
95 static bool arg_all
= false;
96 static PagerFlags arg_pager_flags
= 0;
97 static int arg_lines
= ARG_LINES_DEFAULT
;
98 static bool arg_no_tail
= false;
99 static bool arg_quiet
= false;
100 static bool arg_merge
= false;
101 static bool arg_boot
= false;
102 static sd_id128_t arg_boot_id
= {};
103 static int arg_boot_offset
= 0;
104 static bool arg_dmesg
= false;
105 static bool arg_no_hostname
= false;
106 static const char *arg_cursor
= NULL
;
107 static const char *arg_cursor_file
= NULL
;
108 static const char *arg_after_cursor
= NULL
;
109 static bool arg_show_cursor
= false;
110 static const char *arg_directory
= NULL
;
111 static char **arg_file
= NULL
;
112 static bool arg_file_stdin
= false;
113 static int arg_priorities
= 0xFF;
114 static Set
*arg_facilities
= NULL
;
115 static char *arg_verify_key
= NULL
;
117 static usec_t arg_interval
= DEFAULT_FSS_INTERVAL_USEC
;
118 static bool arg_force
= false;
120 static usec_t arg_since
= 0, arg_until
= 0;
121 static bool arg_since_set
= false, arg_until_set
= false;
122 static char **arg_syslog_identifier
= NULL
;
123 static char **arg_system_units
= NULL
;
124 static char **arg_user_units
= NULL
;
125 static const char *arg_field
= NULL
;
126 static bool arg_catalog
= false;
127 static bool arg_reverse
= false;
128 static int arg_journal_type
= 0;
129 static int arg_namespace_flags
= 0;
130 static char *arg_root
= NULL
;
131 static char *arg_image
= NULL
;
132 static const char *arg_machine
= NULL
;
133 static const char *arg_namespace
= NULL
;
134 static uint64_t arg_vacuum_size
= 0;
135 static uint64_t arg_vacuum_n_files
= 0;
136 static usec_t arg_vacuum_time
= 0;
137 static Set
*arg_output_fields
= NULL
;
138 static const char *arg_pattern
= NULL
;
139 static pcre2_code
*arg_compiled_pattern
= NULL
;
140 static PatternCompileCase arg_case
= PATTERN_COMPILE_CASE_AUTO
;
141 ImagePolicy
*arg_image_policy
= NULL
;
143 STATIC_DESTRUCTOR_REGISTER(arg_file
, strv_freep
);
144 STATIC_DESTRUCTOR_REGISTER(arg_facilities
, set_freep
);
145 STATIC_DESTRUCTOR_REGISTER(arg_verify_key
, freep
);
146 STATIC_DESTRUCTOR_REGISTER(arg_syslog_identifier
, strv_freep
);
147 STATIC_DESTRUCTOR_REGISTER(arg_system_units
, strv_freep
);
148 STATIC_DESTRUCTOR_REGISTER(arg_user_units
, strv_freep
);
149 STATIC_DESTRUCTOR_REGISTER(arg_root
, freep
);
150 STATIC_DESTRUCTOR_REGISTER(arg_image
, freep
);
151 STATIC_DESTRUCTOR_REGISTER(arg_output_fields
, set_freep
);
152 STATIC_DESTRUCTOR_REGISTER(arg_compiled_pattern
, pattern_freep
);
153 STATIC_DESTRUCTOR_REGISTER(arg_image_policy
, image_policy_freep
);
164 ACTION_UPDATE_CATALOG
,
167 ACTION_RELINQUISH_VAR
,
171 ACTION_ROTATE_AND_VACUUM
,
173 ACTION_LIST_FIELD_NAMES
,
174 } arg_action
= ACTION_SHOW
;
176 typedef struct BootId
{
182 static int add_matches_for_device(sd_journal
*j
, const char *devpath
) {
183 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
191 if (!path_startswith(devpath
, "/dev/"))
192 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
193 "Devpath does not start with /dev/");
195 if (stat(devpath
, &st
) < 0)
196 return log_error_errno(errno
, "Couldn't stat file: %m");
198 r
= sd_device_new_from_stat_rdev(&device
, &st
);
200 return log_error_errno(r
, "Failed to get device from devnum " DEVNUM_FORMAT_STR
": %m", DEVNUM_FORMAT_VAL(st
.st_rdev
));
202 for (d
= device
; d
; ) {
203 _cleanup_free_
char *match
= NULL
;
204 const char *subsys
, *sysname
, *devnode
;
207 r
= sd_device_get_subsystem(d
, &subsys
);
211 r
= sd_device_get_sysname(d
, &sysname
);
215 match
= strjoin("_KERNEL_DEVICE=+", subsys
, ":", sysname
);
219 r
= sd_journal_add_match(j
, match
, 0);
221 return log_error_errno(r
, "Failed to add match: %m");
223 if (sd_device_get_devname(d
, &devnode
) >= 0) {
224 _cleanup_free_
char *match1
= NULL
;
226 r
= stat(devnode
, &st
);
228 return log_error_errno(r
, "Failed to stat() device node \"%s\": %m", devnode
);
230 r
= asprintf(&match1
, "_KERNEL_DEVICE=%c" DEVNUM_FORMAT_STR
, S_ISBLK(st
.st_mode
) ? 'b' : 'c', DEVNUM_FORMAT_VAL(st
.st_rdev
));
234 r
= sd_journal_add_match(j
, match1
, 0);
236 return log_error_errno(r
, "Failed to add match: %m");
240 if (sd_device_get_parent(d
, &parent
) < 0)
246 r
= add_match_this_boot(j
, arg_machine
);
248 return log_error_errno(r
, "Failed to add match for the current boot: %m");
253 static char *format_timestamp_maybe_utc(char *buf
, size_t l
, usec_t t
) {
256 return format_timestamp_style(buf
, l
, t
, TIMESTAMP_UTC
);
258 return format_timestamp(buf
, l
, t
);
261 static int parse_boot_descriptor(const char *x
, sd_id128_t
*boot_id
, int *offset
) {
262 sd_id128_t id
= SD_ID128_NULL
;
265 if (streq(x
, "all")) {
266 *boot_id
= SD_ID128_NULL
;
269 } else if (strlen(x
) >= SD_ID128_STRING_MAX
- 1) {
272 t
= strndupa_safe(x
, SD_ID128_STRING_MAX
- 1);
273 r
= sd_id128_from_string(t
, &id
);
275 x
+= SD_ID128_STRING_MAX
- 1;
277 if (!IN_SET(*x
, 0, '-', '+'))
281 r
= safe_atoi(x
, &off
);
286 r
= safe_atoi(x
, &off
);
300 static int help_facilities(void) {
302 puts("Available facilities:");
304 for (int i
= 0; i
< LOG_NFACILITIES
; i
++) {
305 _cleanup_free_
char *t
= NULL
;
307 if (log_facility_unshifted_to_string_alloc(i
, &t
))
315 static int help(void) {
316 _cleanup_free_
char *link
= NULL
;
319 pager_open(arg_pager_flags
);
321 r
= terminal_urlify_man("journalctl", "1", &link
);
325 printf("%1$s [OPTIONS...] [MATCHES...]\n\n"
326 "%5$sQuery the journal.%6$s\n\n"
327 "%3$sSource Options:%4$s\n"
328 " --system Show the system journal\n"
329 " --user Show the user journal for the current user\n"
330 " -M --machine=CONTAINER Operate on local container\n"
331 " -m --merge Show entries from all available journals\n"
332 " -D --directory=PATH Show journal files from directory\n"
333 " --file=PATH Show journal file\n"
334 " --root=PATH Operate on an alternate filesystem root\n"
335 " --image=PATH Operate on disk image as filesystem root\n"
336 " --image-policy=POLICY Specify disk image dissection policy\n"
337 " --namespace=NAMESPACE Show journal data from specified journal namespace\n"
338 "\n%3$sFiltering Options:%4$s\n"
339 " -S --since=DATE Show entries not older than the specified date\n"
340 " -U --until=DATE Show entries not newer than the specified date\n"
341 " -c --cursor=CURSOR Show entries starting at the specified cursor\n"
342 " --after-cursor=CURSOR Show entries after the specified cursor\n"
343 " --cursor-file=FILE Show entries after cursor in FILE and update FILE\n"
344 " -b --boot[=ID] Show current boot or the specified boot\n"
345 " -u --unit=UNIT Show logs from the specified unit\n"
346 " --user-unit=UNIT Show logs from the specified user unit\n"
347 " -t --identifier=STRING Show entries with the specified syslog identifier\n"
348 " -p --priority=RANGE Show entries with the specified priority\n"
349 " --facility=FACILITY... Show entries with the specified facilities\n"
350 " -g --grep=PATTERN Show entries with MESSAGE matching PATTERN\n"
351 " --case-sensitive[=BOOL] Force case sensitive or insensitive matching\n"
352 " -k --dmesg Show kernel message log from the current boot\n"
353 "\n%3$sOutput Control Options:%4$s\n"
354 " -o --output=STRING Change journal output mode (short, short-precise,\n"
355 " short-iso, short-iso-precise, short-full,\n"
356 " short-monotonic, short-unix, verbose, export,\n"
357 " json, json-pretty, json-sse, json-seq, cat,\n"
359 " --output-fields=LIST Select fields to print in verbose/export/json modes\n"
360 " -n --lines[=INTEGER] Number of journal entries to show\n"
361 " -r --reverse Show the newest entries first\n"
362 " --show-cursor Print the cursor after all the entries\n"
363 " --utc Express time in Coordinated Universal Time (UTC)\n"
364 " -x --catalog Add message explanations where available\n"
365 " --no-hostname Suppress output of hostname field\n"
366 " --no-full Ellipsize fields\n"
367 " -a --all Show all fields, including long and unprintable\n"
368 " -f --follow Follow the journal\n"
369 " --no-tail Show all lines, even in follow mode\n"
370 " -q --quiet Do not show info messages and privilege warning\n"
371 "\n%3$sPager Control Options:%4$s\n"
372 " --no-pager Do not pipe output into a pager\n"
373 " -e --pager-end Immediately jump to the end in the pager\n"
374 "\n%3$sForward Secure Sealing (FSS) Options:%4$s\n"
375 " --interval=TIME Time interval for changing the FSS sealing key\n"
376 " --verify-key=KEY Specify FSS verification key\n"
377 " --force Override of the FSS key pair with --setup-keys\n"
378 "\n%3$sCommands:%4$s\n"
379 " -h --help Show this help text\n"
380 " --version Show package version\n"
381 " -N --fields List all field names currently used\n"
382 " -F --field=FIELD List all values that a specified field takes\n"
383 " --list-boots Show terse information about recorded boots\n"
384 " --disk-usage Show total disk usage of all journal files\n"
385 " --vacuum-size=BYTES Reduce disk usage below specified size\n"
386 " --vacuum-files=INT Leave only the specified number of journal files\n"
387 " --vacuum-time=TIME Remove journal files older than specified time\n"
388 " --verify Verify journal file consistency\n"
389 " --sync Synchronize unwritten journal messages to disk\n"
390 " --relinquish-var Stop logging to disk, log to temporary file system\n"
391 " --smart-relinquish-var Similar, but NOP if log directory is on root mount\n"
392 " --flush Flush all journal data from /run into /var\n"
393 " --rotate Request immediate rotation of the journal files\n"
394 " --header Show journal header information\n"
395 " --list-catalog Show all message IDs in the catalog\n"
396 " --dump-catalog Show entries in the message catalog\n"
397 " --update-catalog Update the message catalog database\n"
398 " --setup-keys Generate a new FSS key pair\n"
399 "\nSee the %2$s for details.\n",
400 program_invocation_short_name
,
410 static int parse_argv(int argc
, char *argv
[]) {
446 ARG_SMART_RELINQUISH_VAR
,
456 static const struct option options
[] = {
457 { "help", no_argument
, NULL
, 'h' },
458 { "version" , no_argument
, NULL
, ARG_VERSION
},
459 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
460 { "pager-end", no_argument
, NULL
, 'e' },
461 { "follow", no_argument
, NULL
, 'f' },
462 { "force", no_argument
, NULL
, ARG_FORCE
},
463 { "output", required_argument
, NULL
, 'o' },
464 { "all", no_argument
, NULL
, 'a' },
465 { "full", no_argument
, NULL
, 'l' },
466 { "no-full", no_argument
, NULL
, ARG_NO_FULL
},
467 { "lines", optional_argument
, NULL
, 'n' },
468 { "no-tail", no_argument
, NULL
, ARG_NO_TAIL
},
469 { "new-id128", no_argument
, NULL
, ARG_NEW_ID128
}, /* deprecated */
470 { "quiet", no_argument
, NULL
, 'q' },
471 { "merge", no_argument
, NULL
, 'm' },
472 { "this-boot", no_argument
, NULL
, ARG_THIS_BOOT
}, /* deprecated */
473 { "boot", optional_argument
, NULL
, 'b' },
474 { "list-boots", no_argument
, NULL
, ARG_LIST_BOOTS
},
475 { "dmesg", no_argument
, NULL
, 'k' },
476 { "system", no_argument
, NULL
, ARG_SYSTEM
},
477 { "user", no_argument
, NULL
, ARG_USER
},
478 { "directory", required_argument
, NULL
, 'D' },
479 { "file", required_argument
, NULL
, ARG_FILE
},
480 { "root", required_argument
, NULL
, ARG_ROOT
},
481 { "image", required_argument
, NULL
, ARG_IMAGE
},
482 { "image-policy", required_argument
, NULL
, ARG_IMAGE_POLICY
},
483 { "header", no_argument
, NULL
, ARG_HEADER
},
484 { "identifier", required_argument
, NULL
, 't' },
485 { "priority", required_argument
, NULL
, 'p' },
486 { "facility", required_argument
, NULL
, ARG_FACILITY
},
487 { "grep", required_argument
, NULL
, 'g' },
488 { "case-sensitive", optional_argument
, NULL
, ARG_CASE_SENSITIVE
},
489 { "setup-keys", no_argument
, NULL
, ARG_SETUP_KEYS
},
490 { "interval", required_argument
, NULL
, ARG_INTERVAL
},
491 { "verify", no_argument
, NULL
, ARG_VERIFY
},
492 { "verify-key", required_argument
, NULL
, ARG_VERIFY_KEY
},
493 { "disk-usage", no_argument
, NULL
, ARG_DISK_USAGE
},
494 { "cursor", required_argument
, NULL
, 'c' },
495 { "cursor-file", required_argument
, NULL
, ARG_CURSOR_FILE
},
496 { "after-cursor", required_argument
, NULL
, ARG_AFTER_CURSOR
},
497 { "show-cursor", no_argument
, NULL
, ARG_SHOW_CURSOR
},
498 { "since", required_argument
, NULL
, 'S' },
499 { "until", required_argument
, NULL
, 'U' },
500 { "unit", required_argument
, NULL
, 'u' },
501 { "user-unit", required_argument
, NULL
, ARG_USER_UNIT
},
502 { "field", required_argument
, NULL
, 'F' },
503 { "fields", no_argument
, NULL
, 'N' },
504 { "catalog", no_argument
, NULL
, 'x' },
505 { "list-catalog", no_argument
, NULL
, ARG_LIST_CATALOG
},
506 { "dump-catalog", no_argument
, NULL
, ARG_DUMP_CATALOG
},
507 { "update-catalog", no_argument
, NULL
, ARG_UPDATE_CATALOG
},
508 { "reverse", no_argument
, NULL
, 'r' },
509 { "machine", required_argument
, NULL
, 'M' },
510 { "utc", no_argument
, NULL
, ARG_UTC
},
511 { "flush", no_argument
, NULL
, ARG_FLUSH
},
512 { "relinquish-var", no_argument
, NULL
, ARG_RELINQUISH_VAR
},
513 { "smart-relinquish-var", no_argument
, NULL
, ARG_SMART_RELINQUISH_VAR
},
514 { "sync", no_argument
, NULL
, ARG_SYNC
},
515 { "rotate", no_argument
, NULL
, ARG_ROTATE
},
516 { "vacuum-size", required_argument
, NULL
, ARG_VACUUM_SIZE
},
517 { "vacuum-files", required_argument
, NULL
, ARG_VACUUM_FILES
},
518 { "vacuum-time", required_argument
, NULL
, ARG_VACUUM_TIME
},
519 { "no-hostname", no_argument
, NULL
, ARG_NO_HOSTNAME
},
520 { "output-fields", required_argument
, NULL
, ARG_OUTPUT_FIELDS
},
521 { "namespace", required_argument
, NULL
, ARG_NAMESPACE
},
530 while ((c
= getopt_long(argc
, argv
, "hefo:aln::qmb::kD:p:g:c:S:U:t:u:NF:xrM:", options
, NULL
)) >= 0)
541 arg_pager_flags
|= PAGER_DISABLE
;
545 arg_pager_flags
|= PAGER_JUMP_TO_END
;
547 if (arg_lines
== ARG_LINES_DEFAULT
)
559 if (streq(optarg
, "help")) {
560 DUMP_STRING_TABLE(output_mode
, OutputMode
, _OUTPUT_MODE_MAX
);
564 arg_output
= output_mode_from_string(optarg
);
566 return log_error_errno(arg_output
, "Unknown output format '%s'.", optarg
);
568 if (IN_SET(arg_output
, OUTPUT_EXPORT
, OUTPUT_JSON
, OUTPUT_JSON_PRETTY
, OUTPUT_JSON_SSE
, OUTPUT_JSON_SEQ
, OUTPUT_CAT
))
571 if (OUTPUT_MODE_IS_JSON(arg_output
))
572 arg_json_format_flags
= output_mode_to_json_format_flags(arg_output
) | JSON_FORMAT_COLOR_AUTO
;
574 arg_json_format_flags
= JSON_FORMAT_OFF
;
592 if (streq(optarg
, "all"))
593 arg_lines
= ARG_LINES_ALL
;
595 r
= safe_atoi(optarg
, &arg_lines
);
596 if (r
< 0 || arg_lines
< 0)
597 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to parse lines '%s'", optarg
);
602 /* Hmm, no argument? Maybe the next
603 * word on the command line is
604 * supposed to be the argument? Let's
605 * see if there is one, and is
609 if (streq(argv
[optind
], "all")) {
610 arg_lines
= ARG_LINES_ALL
;
612 } else if (safe_atoi(argv
[optind
], &n
) >= 0 && n
>= 0) {
626 arg_action
= ACTION_NEW_ID128
;
639 arg_boot_id
= SD_ID128_NULL
;
645 arg_boot_id
= SD_ID128_NULL
;
649 r
= parse_boot_descriptor(optarg
, &arg_boot_id
, &arg_boot_offset
);
651 return log_error_errno(r
, "Failed to parse boot descriptor '%s'", optarg
);
655 /* Hmm, no argument? Maybe the next
656 * word on the command line is
657 * supposed to be the argument? Let's
658 * see if there is one and is parsable
659 * as a boot descriptor... */
660 } else if (optind
< argc
) {
661 r
= parse_boot_descriptor(argv
[optind
], &arg_boot_id
, &arg_boot_offset
);
670 arg_action
= ACTION_LIST_BOOTS
;
674 arg_boot
= arg_dmesg
= true;
678 arg_journal_type
|= SD_JOURNAL_SYSTEM
;
682 arg_journal_type
|= SD_JOURNAL_CURRENT_USER
;
686 arg_machine
= optarg
;
690 if (streq(optarg
, "*")) {
691 arg_namespace_flags
= SD_JOURNAL_ALL_NAMESPACES
;
692 arg_namespace
= NULL
;
693 } else if (startswith(optarg
, "+")) {
694 arg_namespace_flags
= SD_JOURNAL_INCLUDE_DEFAULT_NAMESPACE
;
695 arg_namespace
= optarg
+ 1;
696 } else if (isempty(optarg
)) {
697 arg_namespace_flags
= 0;
698 arg_namespace
= NULL
;
700 arg_namespace_flags
= 0;
701 arg_namespace
= optarg
;
707 arg_directory
= optarg
;
711 if (streq(optarg
, "-"))
712 /* An undocumented feature: we can read journal files from STDIN. We don't document
713 * this though, since after all we only support this for mmap-able, seekable files, and
714 * not for example pipes which are probably the primary usecase for reading things from
715 * STDIN. To avoid confusion we hence don't document this feature. */
716 arg_file_stdin
= true;
718 r
= glob_extend(&arg_file
, optarg
, GLOB_NOCHECK
);
720 return log_error_errno(r
, "Failed to add paths: %m");
725 r
= parse_path_argument(optarg
, /* suppress_root= */ true, &arg_root
);
731 r
= parse_path_argument(optarg
, /* suppress_root= */ false, &arg_image
);
736 case ARG_IMAGE_POLICY
:
737 r
= parse_image_policy_argument(optarg
, &arg_image_policy
);
746 case ARG_CURSOR_FILE
:
747 arg_cursor_file
= optarg
;
750 case ARG_AFTER_CURSOR
:
751 arg_after_cursor
= optarg
;
754 case ARG_SHOW_CURSOR
:
755 arg_show_cursor
= true;
759 arg_action
= ACTION_PRINT_HEADER
;
763 arg_action
= ACTION_VERIFY
;
767 arg_action
= ACTION_DISK_USAGE
;
770 case ARG_VACUUM_SIZE
:
771 r
= parse_size(optarg
, 1024, &arg_vacuum_size
);
773 return log_error_errno(r
, "Failed to parse vacuum size: %s", optarg
);
775 arg_action
= arg_action
== ACTION_ROTATE
? ACTION_ROTATE_AND_VACUUM
: ACTION_VACUUM
;
778 case ARG_VACUUM_FILES
:
779 r
= safe_atou64(optarg
, &arg_vacuum_n_files
);
781 return log_error_errno(r
, "Failed to parse vacuum files: %s", optarg
);
783 arg_action
= arg_action
== ACTION_ROTATE
? ACTION_ROTATE_AND_VACUUM
: ACTION_VACUUM
;
786 case ARG_VACUUM_TIME
:
787 r
= parse_sec(optarg
, &arg_vacuum_time
);
789 return log_error_errno(r
, "Failed to parse vacuum time: %s", optarg
);
791 arg_action
= arg_action
== ACTION_ROTATE
? ACTION_ROTATE_AND_VACUUM
: ACTION_VACUUM
;
800 arg_action
= ACTION_SETUP_KEYS
;
804 r
= free_and_strdup(&arg_verify_key
, optarg
);
807 /* Use memset not explicit_bzero() or similar so this doesn't look confusing
808 * in ps or htop output. */
809 memset(optarg
, 'x', strlen(optarg
));
811 arg_action
= ACTION_VERIFY
;
816 r
= parse_sec(optarg
, &arg_interval
);
817 if (r
< 0 || arg_interval
<= 0)
818 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
819 "Failed to parse sealing key change interval: %s", optarg
);
826 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
),
827 "Compiled without forward-secure sealing support.");
833 dots
= strstr(optarg
, "..");
835 _cleanup_free_
char *a
= NULL
;
839 a
= strndup(optarg
, dots
- optarg
);
843 from
= log_level_from_string(a
);
844 to
= log_level_from_string(dots
+ 2);
846 if (from
< 0 || to
< 0)
847 return log_error_errno(from
< 0 ? from
: to
,
848 "Failed to parse log level range %s", optarg
);
853 for (i
= from
; i
<= to
; i
++)
854 arg_priorities
|= 1 << i
;
856 for (i
= to
; i
<= from
; i
++)
857 arg_priorities
|= 1 << i
;
863 p
= log_level_from_string(optarg
);
865 return log_error_errno(p
, "Unknown log level %s", optarg
);
869 for (i
= 0; i
<= p
; i
++)
870 arg_priorities
|= 1 << i
;
880 _cleanup_free_
char *fac
= NULL
;
883 r
= extract_first_word(&p
, &fac
, ",", 0);
885 return log_error_errno(r
, "Failed to parse facilities: %s", optarg
);
889 if (streq(fac
, "help")) {
894 num
= log_facility_unshifted_from_string(fac
);
896 return log_error_errno(num
, "Bad --facility= argument \"%s\".", fac
);
898 if (set_ensure_put(&arg_facilities
, NULL
, INT_TO_PTR(num
)) < 0)
906 arg_pattern
= optarg
;
909 case ARG_CASE_SENSITIVE
:
911 r
= parse_boolean(optarg
);
913 return log_error_errno(r
, "Bad --case-sensitive= argument \"%s\": %m", optarg
);
914 arg_case
= r
? PATTERN_COMPILE_CASE_SENSITIVE
: PATTERN_COMPILE_CASE_INSENSITIVE
;
916 arg_case
= PATTERN_COMPILE_CASE_SENSITIVE
;
921 r
= parse_timestamp(optarg
, &arg_since
);
923 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
924 "Failed to parse timestamp: %s", optarg
);
925 arg_since_set
= true;
929 r
= parse_timestamp(optarg
, &arg_until
);
931 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
932 "Failed to parse timestamp: %s", optarg
);
933 arg_until_set
= true;
937 r
= strv_extend(&arg_syslog_identifier
, optarg
);
943 r
= strv_extend(&arg_system_units
, optarg
);
949 r
= strv_extend(&arg_user_units
, optarg
);
955 arg_action
= ACTION_LIST_FIELDS
;
960 arg_action
= ACTION_LIST_FIELD_NAMES
;
963 case ARG_NO_HOSTNAME
:
964 arg_no_hostname
= true;
971 case ARG_LIST_CATALOG
:
972 arg_action
= ACTION_LIST_CATALOG
;
975 case ARG_DUMP_CATALOG
:
976 arg_action
= ACTION_DUMP_CATALOG
;
979 case ARG_UPDATE_CATALOG
:
980 arg_action
= ACTION_UPDATE_CATALOG
;
992 arg_action
= ACTION_FLUSH
;
995 case ARG_SMART_RELINQUISH_VAR
: {
996 int root_mnt_id
, log_mnt_id
;
998 /* Try to be smart about relinquishing access to /var/log/journal/ during shutdown:
999 * if it's on the same mount as the root file system there's no point in
1000 * relinquishing access and we can leave journald write to it until the very last
1003 r
= path_get_mnt_id("/", &root_mnt_id
);
1005 log_debug_errno(r
, "Failed to get root mount ID, ignoring: %m");
1007 r
= path_get_mnt_id("/var/log/journal/", &log_mnt_id
);
1009 log_debug_errno(r
, "Failed to get journal directory mount ID, ignoring: %m");
1010 else if (root_mnt_id
== log_mnt_id
) {
1011 log_debug("/var/log/journal/ is on root file system, not relinquishing access to /var.");
1014 log_debug("/var/log/journal/ is not on the root file system, relinquishing access to it.");
1020 case ARG_RELINQUISH_VAR
:
1021 arg_action
= ACTION_RELINQUISH_VAR
;
1025 arg_action
= arg_action
== ACTION_VACUUM
? ACTION_ROTATE_AND_VACUUM
: ACTION_ROTATE
;
1029 arg_action
= ACTION_SYNC
;
1032 case ARG_OUTPUT_FIELDS
: {
1033 _cleanup_strv_free_
char **v
= NULL
;
1035 v
= strv_split(optarg
, ",");
1039 r
= set_put_strdupv(&arg_output_fields
, v
);
1049 assert_not_reached();
1053 arg_lines
= ARG_LINES_ALL
;
1055 if (arg_follow
&& !arg_since_set
&& arg_lines
== ARG_LINES_DEFAULT
)
1058 if (arg_follow
&& !arg_merge
&& !arg_boot
) {
1060 arg_boot_id
= SD_ID128_NULL
;
1061 arg_boot_offset
= 0;
1064 if (!!arg_directory
+ !!arg_file
+ !!arg_machine
+ !!arg_root
+ !!arg_image
> 1)
1065 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
1066 "Please specify at most one of -D/--directory=, --file=, -M/--machine=, --root=, --image=.");
1068 if (arg_since_set
&& arg_until_set
&& arg_since
> arg_until
)
1069 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
1070 "--since= must be before --until=.");
1072 if (!!arg_cursor
+ !!arg_after_cursor
+ !!arg_since_set
> 1)
1073 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
1074 "Please specify only one of --since=, --cursor=, and --after-cursor=.");
1076 if (arg_follow
&& arg_reverse
)
1077 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
1078 "Please specify either --reverse= or --follow=, not both.");
1080 if (!IN_SET(arg_action
, ACTION_SHOW
, ACTION_DUMP_CATALOG
, ACTION_LIST_CATALOG
) && optind
< argc
)
1081 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
1082 "Extraneous arguments starting with '%s'",
1085 if ((arg_boot
|| arg_action
== ACTION_LIST_BOOTS
) && arg_merge
)
1086 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
1087 "Using --boot or --list-boots with --merge is not supported.");
1089 if (!strv_isempty(arg_system_units
) && arg_journal_type
== SD_JOURNAL_CURRENT_USER
) {
1090 /* Specifying --user and --unit= at the same time makes no sense (as the former excludes the user
1091 * journal, but the latter excludes the system journal, thus resulting in empty output). Let's be nice
1092 * to users, and automatically turn --unit= into --user-unit= if combined with --user. */
1093 r
= strv_extend_strv(&arg_user_units
, arg_system_units
, true);
1097 arg_system_units
= strv_free(arg_system_units
);
1101 r
= pattern_compile_and_log(arg_pattern
, arg_case
, &arg_compiled_pattern
);
1105 /* When --grep is used along with --lines, we don't know how many lines we can print.
1106 * So we search backwards and count until enough lines have been printed or we hit the head.
1107 * An exception is that --follow might set arg_lines, so let's not imply --reverse
1108 * if that is specified. */
1109 if (arg_lines
>= 0 && !arg_follow
)
1116 static int add_matches(sd_journal
*j
, char **args
) {
1117 bool have_term
= false;
1121 STRV_FOREACH(i
, args
) {
1124 if (streq(*i
, "+")) {
1127 r
= sd_journal_add_disjunction(j
);
1130 } else if (path_is_absolute(*i
)) {
1131 _cleanup_free_
char *p
= NULL
, *t
= NULL
, *t2
= NULL
, *interpreter
= NULL
;
1134 r
= chase(*i
, NULL
, CHASE_TRAIL_SLASH
, &p
, NULL
);
1136 return log_error_errno(r
, "Couldn't canonicalize path: %m");
1138 if (lstat(p
, &st
) < 0)
1139 return log_error_errno(errno
, "Couldn't stat file: %m");
1141 if (S_ISREG(st
.st_mode
) && (0111 & st
.st_mode
)) {
1142 if (executable_is_script(p
, &interpreter
) > 0) {
1143 _cleanup_free_
char *comm
= NULL
;
1145 r
= path_extract_filename(p
, &comm
);
1147 return log_error_errno(r
, "Failed to extract filename of '%s': %m", p
);
1149 t
= strjoin("_COMM=", strshorten(comm
, TASK_COMM_LEN
-1));
1153 /* Append _EXE only if the interpreter is not a link.
1154 Otherwise, it might be outdated often. */
1155 if (lstat(interpreter
, &st
) == 0 && !S_ISLNK(st
.st_mode
)) {
1156 t2
= strjoin("_EXE=", interpreter
);
1161 t
= strjoin("_EXE=", p
);
1166 r
= sd_journal_add_match(j
, t
, 0);
1169 r
= sd_journal_add_match(j
, t2
, 0);
1171 } else if (S_ISCHR(st
.st_mode
) || S_ISBLK(st
.st_mode
)) {
1172 r
= add_matches_for_device(j
, p
);
1176 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
1177 "File is neither a device node, nor regular file, nor executable: %s",
1182 r
= sd_journal_add_match(j
, *i
, 0);
1187 return log_error_errno(r
, "Failed to add match '%s': %m", *i
);
1190 if (!strv_isempty(args
) && !have_term
)
1191 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
1192 "\"+\" can only be used between terms");
1197 static int discover_next_boot(
1199 sd_id128_t previous_boot_id
,
1209 /* We expect the journal to be on the last position of a boot
1210 * (in relation to the direction we are going), so that the next
1211 * invocation of sd_journal_next/previous will be from a different
1212 * boot. We then collect any information we desire and then jump
1213 * to the last location of the new boot by using a _BOOT_ID match
1214 * coming from the other journal direction. */
1216 /* Make sure we aren't restricted by any _BOOT_ID matches, so that
1217 * we can actually advance to a *different* boot. */
1218 sd_journal_flush_matches(j
);
1222 r
= sd_journal_previous(j
);
1224 r
= sd_journal_next(j
);
1229 return 0; /* End of journal, yay. */
1232 r
= sd_journal_get_monotonic_usec(j
, NULL
, &boot
.id
);
1236 /* We iterate through this in a loop, until the boot ID differs from the previous one. Note that
1237 * normally, this will only require a single iteration, as we seeked to the last entry of the previous
1238 * boot entry already. However, it might happen that the per-journal-field entry arrays are less
1239 * complete than the main entry array, and hence might reference an entry that's not actually the last
1240 * one of the boot ID as last one. Let's hence use the per-field array is initial seek position to
1241 * speed things up, but let's not trust that it is complete, and hence, manually advance as
1244 } while (sd_id128_equal(boot
.id
, previous_boot_id
));
1246 r
= sd_journal_get_realtime_usec(j
, &boot
.first_usec
);
1250 /* Now seek to the last occurrence of this boot ID. */
1251 r
= add_match_boot_id(j
, boot
.id
);
1256 r
= sd_journal_seek_head(j
);
1258 r
= sd_journal_seek_tail(j
);
1263 r
= sd_journal_next(j
);
1265 r
= sd_journal_previous(j
);
1269 return log_debug_errno(SYNTHETIC_ERRNO(ENODATA
),
1270 "Whoopsie! We found a boot ID but can't read its last entry."); /* This shouldn't happen. We just came from this very boot ID. */
1272 r
= sd_journal_get_realtime_usec(j
, &boot
.last_usec
);
1276 sd_journal_flush_matches(j
);
1281 static int find_boot_by_id(sd_journal
*j
) {
1286 sd_journal_flush_matches(j
);
1288 r
= add_match_boot_id(j
, arg_boot_id
);
1292 r
= sd_journal_seek_head(j
); /* seek to oldest */
1296 r
= sd_journal_next(j
); /* read the oldest entry */
1300 /* At this point the read pointer is positioned at the oldest occurrence of the reference boot ID.
1301 * After flushing the matches, one more invocation of _previous() will hence place us at the
1302 * following entry, which must then have an older boot ID */
1304 sd_journal_flush_matches(j
);
1308 static int find_boot_by_offset(sd_journal
*j
) {
1309 bool advance_older
, skip_once
;
1312 /* Adjust for the asymmetry that offset 0 is the last (and current) boot, while 1 is considered the
1313 * (chronological) first boot in the journal. */
1314 advance_older
= skip_once
= arg_boot_offset
<= 0;
1317 r
= sd_journal_seek_tail(j
); /* seek to newest */
1319 r
= sd_journal_seek_head(j
); /* seek to oldest */
1323 /* No sd_journal_next()/_previous() here.
1325 * At this point the read pointer is positioned after the newest/before the oldest entry in the whole
1326 * journal. The next invocation of _previous()/_next() will hence position us at the newest/oldest
1329 int offset
= arg_boot_offset
;
1330 sd_id128_t previous_boot_id
= SD_ID128_NULL
;
1334 r
= discover_next_boot(j
, previous_boot_id
, advance_older
, &boot
);
1338 previous_boot_id
= boot
.id
;
1341 offset
+= advance_older
? 1 : -1;
1345 arg_boot_id
= boot
.id
;
1351 static int get_boots(sd_journal
*j
, BootId
**ret_boots
, size_t *ret_n_boots
) {
1352 _cleanup_free_ BootId
*boots
= NULL
;
1358 assert(ret_n_boots
);
1360 r
= sd_journal_seek_head(j
); /* seek to oldest */
1364 /* No sd_journal_next()/_previous() here.
1366 * At this point the read pointer is positioned before the oldest entry in the whole journal. The
1367 * next invocation of _next() will hence position us at the oldest entry we have. */
1369 sd_id128_t previous_boot_id
= SD_ID128_NULL
;
1373 r
= discover_next_boot(j
, previous_boot_id
, /* advance_older = */ false, &boot
);
1379 previous_boot_id
= boot
.id
;
1381 FOREACH_ARRAY(i
, boots
, n_boots
)
1382 if (sd_id128_equal(i
->id
, boot
.id
))
1383 /* The boot id is already stored, something wrong with the journal files.
1384 * Exiting as otherwise this problem would cause an infinite loop. */
1387 if (!GREEDY_REALLOC(boots
, n_boots
+ 1))
1390 boots
[n_boots
++] = boot
;
1393 *ret_boots
= TAKE_PTR(boots
);
1394 *ret_n_boots
= n_boots
;
1398 static int list_boots(sd_journal
*j
) {
1399 _cleanup_(table_unrefp
) Table
*table
= NULL
;
1400 _cleanup_free_ BootId
*boots
= NULL
;
1406 r
= get_boots(j
, &boots
, &n_boots
);
1408 return log_error_errno(r
, "Failed to determine boots: %m");
1412 table
= table_new("idx", "boot id", "first entry", "last entry");
1417 table_set_width(table
, 0);
1419 r
= table_set_json_field_name(table
, 0, "index");
1421 return log_error_errno(r
, "Failed to set JSON field name of column 0: %m");
1423 (void) table_set_sort(table
, (size_t) 0);
1424 (void) table_set_reverse(table
, 0, arg_reverse
);
1426 FOREACH_ARRAY(i
, boots
, n_boots
) {
1427 r
= table_add_many(table
,
1428 TABLE_INT
, (int)(i
- boots
) - (int) n_boots
+ 1,
1429 TABLE_SET_ALIGN_PERCENT
, 100,
1431 TABLE_TIMESTAMP
, i
->first_usec
,
1432 TABLE_TIMESTAMP
, i
->last_usec
);
1434 return table_log_add_error(r
);
1437 r
= table_print_with_pager(table
, arg_json_format_flags
, arg_pager_flags
, !arg_quiet
);
1439 return table_log_print_error(r
);
1444 static int add_boot(sd_journal
*j
) {
1452 /* Take a shortcut and use the current boot_id, which we can do very quickly.
1453 * We can do this only when we logs are coming from the current machine,
1454 * so take the slow path if log location is specified. */
1455 if (arg_boot_offset
== 0 && sd_id128_is_null(arg_boot_id
) &&
1456 !arg_directory
&& !arg_file
&& !arg_root
)
1457 return add_match_this_boot(j
, arg_machine
);
1459 if (sd_id128_is_null(arg_boot_id
)) {
1460 r
= find_boot_by_offset(j
);
1462 return log_error_errno(r
, "Failed to find journal entry from the specified boot offset (%+i): %m",
1465 return log_error_errno(SYNTHETIC_ERRNO(ENODATA
),
1466 "No journal boot entry found from the specified boot offset (%+i).",
1469 r
= find_boot_by_id(j
);
1471 return log_error_errno(r
, "Failed to find journal entry from the specified boot ID (%s): %m",
1472 SD_ID128_TO_STRING(arg_boot_id
));
1474 return log_error_errno(SYNTHETIC_ERRNO(ENODATA
),
1475 "No journal boot entry found from the specified boot ID (%s).",
1476 SD_ID128_TO_STRING(arg_boot_id
));
1479 r
= add_match_boot_id(j
, arg_boot_id
);
1481 return log_error_errno(r
, "Failed to add match: %m");
1483 r
= sd_journal_add_conjunction(j
);
1485 return log_error_errno(r
, "Failed to add conjunction: %m");
1490 static int add_dmesg(sd_journal
*j
) {
1497 r
= sd_journal_add_match(j
, "_TRANSPORT=kernel",
1498 STRLEN("_TRANSPORT=kernel"));
1500 return log_error_errno(r
, "Failed to add match: %m");
1502 r
= sd_journal_add_conjunction(j
);
1504 return log_error_errno(r
, "Failed to add conjunction: %m");
1509 static int get_possible_units(
1515 _cleanup_set_free_free_ Set
*found
= NULL
;
1518 found
= set_new(&string_hash_ops
);
1522 NULSTR_FOREACH(field
, fields
) {
1526 r
= sd_journal_query_unique(j
, field
);
1530 SD_JOURNAL_FOREACH_UNIQUE(j
, data
, size
) {
1533 _cleanup_free_
char *u
= NULL
;
1535 eq
= memchr(data
, '=', size
);
1537 prefix
= eq
- (char*) data
+ 1;
1541 u
= strndup((char*) data
+ prefix
, size
- prefix
);
1545 STRV_FOREACH(pattern
, patterns
)
1546 if (fnmatch(*pattern
, u
, FNM_NOESCAPE
) == 0) {
1547 log_debug("Matched %s with pattern %s=%s", u
, field
, *pattern
);
1549 r
= set_consume(found
, u
);
1551 if (r
< 0 && r
!= -EEXIST
)
1559 *units
= TAKE_PTR(found
);
1564 /* This list is supposed to return the superset of unit names
1565 * possibly matched by rules added with add_matches_for_unit... */
1566 #define SYSTEM_UNITS \
1570 "OBJECT_SYSTEMD_UNIT\0" \
1573 /* ... and add_matches_for_user_unit */
1574 #define USER_UNITS \
1575 "_SYSTEMD_USER_UNIT\0" \
1577 "COREDUMP_USER_UNIT\0" \
1578 "OBJECT_SYSTEMD_USER_UNIT\0" \
1579 "_SYSTEMD_USER_SLICE\0"
1581 static int add_units(sd_journal
*j
) {
1582 _cleanup_strv_free_
char **patterns
= NULL
;
1587 STRV_FOREACH(i
, arg_system_units
) {
1588 _cleanup_free_
char *u
= NULL
;
1590 r
= unit_name_mangle(*i
, UNIT_NAME_MANGLE_GLOB
| (arg_quiet
? 0 : UNIT_NAME_MANGLE_WARN
), &u
);
1594 if (string_is_glob(u
)) {
1595 r
= strv_push(&patterns
, u
);
1600 r
= add_matches_for_unit(j
, u
);
1603 r
= sd_journal_add_disjunction(j
);
1610 if (!strv_isempty(patterns
)) {
1611 _cleanup_set_free_free_ Set
*units
= NULL
;
1614 r
= get_possible_units(j
, SYSTEM_UNITS
, patterns
, &units
);
1618 SET_FOREACH(u
, units
) {
1619 r
= add_matches_for_unit(j
, u
);
1622 r
= sd_journal_add_disjunction(j
);
1629 patterns
= strv_free(patterns
);
1631 STRV_FOREACH(i
, arg_user_units
) {
1632 _cleanup_free_
char *u
= NULL
;
1634 r
= unit_name_mangle(*i
, UNIT_NAME_MANGLE_GLOB
| (arg_quiet
? 0 : UNIT_NAME_MANGLE_WARN
), &u
);
1638 if (string_is_glob(u
)) {
1639 r
= strv_push(&patterns
, u
);
1644 r
= add_matches_for_user_unit(j
, u
, getuid());
1647 r
= sd_journal_add_disjunction(j
);
1654 if (!strv_isempty(patterns
)) {
1655 _cleanup_set_free_free_ Set
*units
= NULL
;
1658 r
= get_possible_units(j
, USER_UNITS
, patterns
, &units
);
1662 SET_FOREACH(u
, units
) {
1663 r
= add_matches_for_user_unit(j
, u
, getuid());
1666 r
= sd_journal_add_disjunction(j
);
1673 /* Complain if the user request matches but nothing whatsoever was
1674 * found, since otherwise everything would be matched. */
1675 if (!(strv_isempty(arg_system_units
) && strv_isempty(arg_user_units
)) && count
== 0)
1678 r
= sd_journal_add_conjunction(j
);
1685 static int add_priorities(sd_journal
*j
) {
1686 char match
[] = "PRIORITY=0";
1690 if (arg_priorities
== 0xFF)
1693 for (i
= LOG_EMERG
; i
<= LOG_DEBUG
; i
++)
1694 if (arg_priorities
& (1 << i
)) {
1695 match
[sizeof(match
)-2] = '0' + i
;
1697 r
= sd_journal_add_match(j
, match
, strlen(match
));
1699 return log_error_errno(r
, "Failed to add match: %m");
1702 r
= sd_journal_add_conjunction(j
);
1704 return log_error_errno(r
, "Failed to add conjunction: %m");
1709 static int add_facilities(sd_journal
*j
) {
1713 SET_FOREACH(p
, arg_facilities
) {
1714 char match
[STRLEN("SYSLOG_FACILITY=") + DECIMAL_STR_MAX(int)];
1716 xsprintf(match
, "SYSLOG_FACILITY=%d", PTR_TO_INT(p
));
1718 r
= sd_journal_add_match(j
, match
, strlen(match
));
1720 return log_error_errno(r
, "Failed to add match: %m");
1726 static int add_syslog_identifier(sd_journal
*j
) {
1731 STRV_FOREACH(i
, arg_syslog_identifier
) {
1732 _cleanup_free_
char *u
= NULL
;
1734 u
= strjoin("SYSLOG_IDENTIFIER=", *i
);
1737 r
= sd_journal_add_match(j
, u
, 0);
1740 r
= sd_journal_add_disjunction(j
);
1745 r
= sd_journal_add_conjunction(j
);
1753 static int format_journal_url(
1763 _cleanup_(memstream_done
) MemStream m
= {};
1767 assert(seed_size
> 0);
1769 f
= memstream_init(&m
);
1776 for (size_t i
= 0; i
< seed_size
; i
++) {
1777 if (i
> 0 && i
% 3 == 0)
1779 fprintf(f
, "%02x", ((uint8_t*) seed
)[i
]);
1782 fprintf(f
, "/%"PRIx64
"-%"PRIx64
, start
, interval
);
1785 fprintf(f
, "?machine=" SD_ID128_FORMAT_STR
, SD_ID128_FORMAT_VAL(machine
));
1787 fprintf(f
, ";hostname=%s", hn
);
1790 return memstream_finalize(&m
, ret_url
, NULL
);
1794 static int setup_keys(void) {
1796 size_t mpk_size
, seed_size
, state_size
;
1797 _cleanup_(unlink_and_freep
) char *k
= NULL
;
1798 _cleanup_free_
char *p
= NULL
;
1799 uint8_t *mpk
, *seed
, *state
;
1800 _cleanup_close_
int fd
= -EBADF
;
1801 sd_id128_t machine
, boot
;
1806 r
= stat("/var/log/journal", &st
);
1807 if (r
< 0 && !IN_SET(errno
, ENOENT
, ENOTDIR
))
1808 return log_error_errno(errno
, "stat(\"%s\") failed: %m", "/var/log/journal");
1810 if (r
< 0 || !S_ISDIR(st
.st_mode
)) {
1811 log_error("%s is not a directory, must be using persistent logging for FSS.",
1812 "/var/log/journal");
1813 return r
< 0 ? -errno
: -ENOTDIR
;
1816 r
= sd_id128_get_machine(&machine
);
1818 return log_error_errno(r
, "Failed to get machine ID: %m");
1820 r
= sd_id128_get_boot(&boot
);
1822 return log_error_errno(r
, "Failed to get boot ID: %m");
1824 if (asprintf(&p
, "/var/log/journal/" SD_ID128_FORMAT_STR
"/fss",
1825 SD_ID128_FORMAT_VAL(machine
)) < 0)
1830 if (r
< 0 && errno
!= ENOENT
)
1831 return log_error_errno(errno
, "unlink(\"%s\") failed: %m", p
);
1832 } else if (access(p
, F_OK
) >= 0)
1833 return log_error_errno(SYNTHETIC_ERRNO(EEXIST
),
1834 "Sealing key file %s exists already. Use --force to recreate.", p
);
1836 if (asprintf(&k
, "/var/log/journal/" SD_ID128_FORMAT_STR
"/fss.tmp.XXXXXX",
1837 SD_ID128_FORMAT_VAL(machine
)) < 0)
1840 mpk_size
= FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR
);
1841 mpk
= alloca_safe(mpk_size
);
1843 seed_size
= FSPRG_RECOMMENDED_SEEDLEN
;
1844 seed
= alloca_safe(seed_size
);
1846 state_size
= FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR
);
1847 state
= alloca_safe(state_size
);
1849 log_info("Generating seed...");
1850 r
= crypto_random_bytes(seed
, seed_size
);
1852 return log_error_errno(r
, "Failed to acquire random seed: %m");
1854 log_info("Generating key pair...");
1855 FSPRG_GenMK(NULL
, mpk
, seed
, seed_size
, FSPRG_RECOMMENDED_SECPAR
);
1857 log_info("Generating sealing key...");
1858 FSPRG_GenState0(state
, mpk
, seed
, seed_size
);
1860 assert(arg_interval
> 0);
1862 n
= now(CLOCK_REALTIME
);
1866 fd
= mkostemp_safe(k
);
1868 return log_error_errno(fd
, "Failed to open %s: %m", k
);
1870 r
= chattr_secret(fd
, CHATTR_WARN_UNSUPPORTED_FLAGS
);
1872 log_full_errno(ERRNO_IS_NOT_SUPPORTED(r
) ? LOG_DEBUG
: LOG_WARNING
,
1873 r
, "Failed to set file attributes on '%s', ignoring: %m", k
);
1875 struct FSSHeader h
= {
1876 .signature
= { 'K', 'S', 'H', 'H', 'R', 'H', 'L', 'P' },
1877 .machine_id
= machine
,
1879 .header_size
= htole64(sizeof(h
)),
1880 .start_usec
= htole64(n
* arg_interval
),
1881 .interval_usec
= htole64(arg_interval
),
1882 .fsprg_secpar
= htole16(FSPRG_RECOMMENDED_SECPAR
),
1883 .fsprg_state_size
= htole64(state_size
),
1886 r
= loop_write(fd
, &h
, sizeof(h
), false);
1888 return log_error_errno(r
, "Failed to write header: %m");
1890 r
= loop_write(fd
, state
, state_size
, false);
1892 return log_error_errno(r
, "Failed to write state: %m");
1894 if (rename(k
, p
) < 0)
1895 return log_error_errno(errno
, "Failed to link file: %m");
1899 _cleanup_free_
char *hn
= NULL
, *key
= NULL
;
1901 r
= format_journal_url(seed
, seed_size
, n
, arg_interval
, hn
, machine
, false, &key
);
1906 hn
= gethostname_malloc();
1908 hostname_cleanup(hn
);
1911 "\nNew keys have been generated for host %s%s" SD_ID128_FORMAT_STR
".\n"
1913 "The %ssecret sealing key%s has been written to the following local file.\n"
1914 "This key file is automatically updated when the sealing key is advanced.\n"
1915 "It should not be used on multiple hosts.\n"
1919 "The sealing key is automatically changed every %s.\n"
1921 "Please write down the following %ssecret verification key%s. It should be stored\n"
1922 "in a safe location and should not be saved locally on disk.\n"
1924 strempty(hn
), hn
? "/" : "",
1925 SD_ID128_FORMAT_VAL(machine
),
1926 ansi_highlight(), ansi_normal(),
1928 FORMAT_TIMESPAN(arg_interval
, 0),
1929 ansi_highlight(), ansi_normal(),
1930 ansi_highlight_red());
1937 fprintf(stderr
, "%s", ansi_normal());
1939 _cleanup_free_
char *url
= NULL
;
1940 r
= format_journal_url(seed
, seed_size
, n
, arg_interval
, hn
, machine
, true, &url
);
1944 (void) print_qrcode(stderr
,
1945 "To transfer the verification key to your phone scan the QR code below",
1952 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
),
1953 "Forward-secure sealing not available.");
1957 static int verify(sd_journal
*j
, bool verbose
) {
1963 log_show_color(true);
1965 ORDERED_HASHMAP_FOREACH(f
, j
->files
) {
1967 usec_t first
= 0, validated
= 0, last
= 0;
1970 if (!arg_verify_key
&& JOURNAL_HEADER_SEALED(f
->header
))
1971 log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f
->path
);
1974 k
= journal_file_verify(f
, arg_verify_key
, &first
, &validated
, &last
, verbose
);
1976 /* If the key was invalid give up right-away. */
1979 r
= log_warning_errno(k
, "FAIL: %s (%m)", f
->path
);
1981 char a
[FORMAT_TIMESTAMP_MAX
], b
[FORMAT_TIMESTAMP_MAX
];
1982 log_full(verbose
? LOG_INFO
: LOG_DEBUG
, "PASS: %s", f
->path
);
1984 if (arg_verify_key
&& JOURNAL_HEADER_SEALED(f
->header
)) {
1985 if (validated
> 0) {
1986 log_full(verbose
? LOG_INFO
: LOG_DEBUG
,
1987 "=> Validated from %s to %s, final %s entries not sealed.",
1988 format_timestamp_maybe_utc(a
, sizeof(a
), first
),
1989 format_timestamp_maybe_utc(b
, sizeof(b
), validated
),
1990 FORMAT_TIMESPAN(last
> validated
? last
- validated
: 0, 0));
1991 } else if (last
> 0)
1992 log_full(verbose
? LOG_INFO
: LOG_DEBUG
,
1993 "=> No sealing yet, %s of entries not sealed.",
1994 FORMAT_TIMESPAN(last
- first
, 0));
1996 log_full(verbose
? LOG_INFO
: LOG_DEBUG
,
1997 "=> No sealing yet, no entries in file.");
2005 static int simple_varlink_call(const char *option
, const char *method
) {
2006 _cleanup_(varlink_flush_close_unrefp
) Varlink
*link
= NULL
;
2007 const char *error
, *fn
;
2011 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
), "%s is not supported in conjunction with --machine=.", option
);
2013 fn
= arg_namespace
?
2014 strjoina("/run/systemd/journal.", arg_namespace
, "/io.systemd.journal") :
2015 "/run/systemd/journal/io.systemd.journal";
2017 r
= varlink_connect_address(&link
, fn
);
2019 return log_error_errno(r
, "Failed to connect to %s: %m", fn
);
2021 (void) varlink_set_description(link
, "journal");
2022 (void) varlink_set_relative_timeout(link
, USEC_INFINITY
);
2024 r
= varlink_call(link
, method
, NULL
, NULL
, &error
, NULL
);
2026 return log_error_errno(r
, "Failed to execute varlink call: %m");
2028 return log_error_errno(SYNTHETIC_ERRNO(ENOANO
),
2029 "Failed to execute varlink call: %s", error
);
2034 static int flush_to_var(void) {
2035 if (access("/run/systemd/journal/flushed", F_OK
) >= 0)
2036 return 0; /* Already flushed, no need to contact journald */
2037 if (errno
!= ENOENT
)
2038 return log_error_errno(errno
, "Unable to check for existence of /run/systemd/journal/flushed: %m");
2040 return simple_varlink_call("--flush", "io.systemd.Journal.FlushToVar");
2043 static int relinquish_var(void) {
2044 return simple_varlink_call("--relinquish-var/--smart-relinquish-var", "io.systemd.Journal.RelinquishVar");
2047 static int rotate(void) {
2048 return simple_varlink_call("--rotate", "io.systemd.Journal.Rotate");
2051 static int sync_journal(void) {
2052 return simple_varlink_call("--sync", "io.systemd.Journal.Synchronize");
2055 static int action_list_fields(sd_journal
*j
) {
2062 r
= sd_journal_set_data_threshold(j
, 0);
2064 return log_error_errno(r
, "Failed to unset data size threshold: %m");
2066 r
= sd_journal_query_unique(j
, arg_field
);
2068 return log_error_errno(r
, "Failed to query unique data objects: %m");
2070 SD_JOURNAL_FOREACH_UNIQUE(j
, data
, size
) {
2073 if (arg_lines
>= 0 && n_shown
>= arg_lines
)
2076 eq
= memchr(data
, '=', size
);
2078 printf("%.*s\n", (int) (size
- ((const uint8_t*) eq
- (const uint8_t*) data
+ 1)), (const char*) eq
+ 1);
2080 printf("%.*s\n", (int) size
, (const char*) data
);
2088 static int update_cursor(sd_journal
*j
) {
2089 _cleanup_free_
char *cursor
= NULL
;
2094 if (!arg_show_cursor
&& !arg_cursor_file
)
2097 r
= sd_journal_get_cursor(j
, &cursor
);
2098 if (r
== -EADDRNOTAVAIL
)
2101 return log_error_errno(r
, "Failed to get cursor: %m");
2103 if (arg_show_cursor
)
2104 printf("-- cursor: %s\n", cursor
);
2106 if (arg_cursor_file
) {
2107 r
= write_string_file(arg_cursor_file
, cursor
, WRITE_STRING_FILE_CREATE
| WRITE_STRING_FILE_ATOMIC
);
2109 return log_error_errno(r
, "Failed to write new cursor to %s: %m", arg_cursor_file
);
2115 typedef struct Context
{
2116 sd_journal
*journal
;
2120 bool previous_boot_id_valid
;
2121 sd_id128_t previous_boot_id
;
2122 sd_id128_t previous_boot_id_output
;
2123 dual_timestamp previous_ts_output
;
2126 static int show(Context
*c
) {
2132 j
= ASSERT_PTR(c
->journal
);
2134 while (arg_lines
< 0 || n_shown
< arg_lines
|| arg_follow
) {
2136 size_t highlight
[2] = {};
2139 r
= sd_journal_step_one(j
, !arg_reverse
);
2141 return log_error_errno(r
, "Failed to iterate through journal: %m");
2146 if (arg_until_set
&& !arg_reverse
&& (arg_lines
< 0 || arg_since_set
)) {
2147 /* If --lines= is set, we usually rely on the n_shown to tell us
2148 * when to stop. However, if --since= is set too, we may end up
2149 * having less than --lines= to output. In this case let's also
2150 * check if the entry is in range. */
2154 r
= sd_journal_get_realtime_usec(j
, &usec
);
2156 return log_error_errno(r
, "Failed to determine timestamp: %m");
2157 if (usec
> arg_until
)
2161 if (arg_since_set
&& (arg_reverse
|| !c
->since_seeked
)) {
2164 r
= sd_journal_get_realtime_usec(j
, &usec
);
2166 return log_error_errno(r
, "Failed to determine timestamp: %m");
2168 if (usec
< arg_since
) {
2170 break; /* Reached the earliest entry */
2172 /* arg_lines >= 0 (!since_seeked):
2173 * We jumped arg_lines back and it seems to be too much */
2174 r
= sd_journal_seek_realtime_usec(j
, arg_since
);
2176 return log_error_errno(r
, "Failed to seek to date: %m");
2177 c
->since_seeked
= true;
2179 c
->need_seek
= true;
2182 c
->since_seeked
= true; /* We're surely within the range of --since now */
2185 if (!arg_merge
&& !arg_quiet
) {
2188 r
= sd_journal_get_monotonic_usec(j
, NULL
, &boot_id
);
2190 if (c
->previous_boot_id_valid
&&
2191 !sd_id128_equal(boot_id
, c
->previous_boot_id
))
2192 printf("%s-- Boot "SD_ID128_FORMAT_STR
" --%s\n",
2193 ansi_highlight(), SD_ID128_FORMAT_VAL(boot_id
), ansi_normal());
2195 c
->previous_boot_id
= boot_id
;
2196 c
->previous_boot_id_valid
= true;
2200 if (arg_compiled_pattern
) {
2201 const void *message
;
2204 r
= sd_journal_get_data(j
, "MESSAGE", &message
, &len
);
2207 c
->need_seek
= true;
2211 return log_error_errno(r
, "Failed to get MESSAGE field: %m");
2214 assert_se(message
= startswith(message
, "MESSAGE="));
2216 r
= pattern_matches_and_log(arg_compiled_pattern
, message
,
2217 len
- strlen("MESSAGE="), highlight
);
2221 c
->need_seek
= true;
2227 arg_all
* OUTPUT_SHOW_ALL
|
2228 arg_full
* OUTPUT_FULL_WIDTH
|
2229 colors_enabled() * OUTPUT_COLOR
|
2230 arg_catalog
* OUTPUT_CATALOG
|
2231 arg_utc
* OUTPUT_UTC
|
2232 arg_no_hostname
* OUTPUT_NO_HOSTNAME
;
2234 r
= show_journal_entry(stdout
, j
, arg_output
, 0, flags
,
2235 arg_output_fields
, highlight
, &c
->ellipsized
,
2236 &c
->previous_ts_output
, &c
->previous_boot_id_output
);
2237 c
->need_seek
= true;
2238 if (r
== -EADDRNOTAVAIL
)
2245 /* If journalctl take a long time to process messages, and during that time journal file
2246 * rotation occurs, a journalctl client will keep those rotated files open until it calls
2247 * sd_journal_process(), which typically happens as a result of calling sd_journal_wait() below
2248 * in the "following" case. By periodically calling sd_journal_process() during the processing
2249 * loop we shrink the window of time a client instance has open file descriptors for rotated
2250 * (deleted) journal files. */
2251 if ((n_shown
% PROCESS_INOTIFY_INTERVAL
) == 0) {
2252 r
= sd_journal_process(j
);
2254 return log_error_errno(r
, "Failed to process inotify events: %m");
2261 static int show_and_fflush(Context
*c
, sd_event_source
*s
) {
2269 return sd_event_exit(sd_event_source_get_event(s
), r
);
2275 static int on_journal_event(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
2276 Context
*c
= ASSERT_PTR(userdata
);
2281 r
= sd_journal_process(c
->journal
);
2283 log_error_errno(r
, "Failed to process journal events: %m");
2284 return sd_event_exit(sd_event_source_get_event(s
), r
);
2287 return show_and_fflush(c
, s
);
2290 static int on_first_event(sd_event_source
*s
, void *userdata
) {
2291 return show_and_fflush(userdata
, s
);
2294 static int on_signal(sd_event_source
*s
, const struct signalfd_siginfo
*si
, void *userdata
) {
2297 assert(IN_SET(si
->ssi_signo
, SIGTERM
, SIGINT
));
2299 return sd_event_exit(sd_event_source_get_event(s
), si
->ssi_signo
);
2302 static int setup_event(Context
*c
, int fd
, sd_event
**ret
) {
2303 _cleanup_(sd_event_unrefp
) sd_event
*e
= NULL
;
2311 r
= sd_event_default(&e
);
2313 return log_error_errno(r
, "Failed to allocate sd_event object: %m");
2315 (void) sd_event_add_signal(e
, NULL
, SIGTERM
| SD_EVENT_SIGNAL_PROCMASK
, on_signal
, NULL
);
2316 (void) sd_event_add_signal(e
, NULL
, SIGINT
| SD_EVENT_SIGNAL_PROCMASK
, on_signal
, NULL
);
2318 r
= sd_event_add_io(e
, NULL
, fd
, EPOLLIN
, &on_journal_event
, c
);
2320 return log_error_errno(r
, "Failed to add io event source for journal: %m");
2322 /* Also keeps an eye on STDOUT, and exits as soon as we see a POLLHUP on that, i.e. when it is closed. */
2323 r
= sd_event_add_io(e
, NULL
, STDOUT_FILENO
, EPOLLHUP
|EPOLLERR
, NULL
, INT_TO_PTR(-ECANCELED
));
2325 return log_error_errno(r
, "Failed to add io event source for stdout: %m");
2327 if (arg_lines
!= 0 || arg_since_set
) {
2328 r
= sd_event_add_defer(e
, NULL
, on_first_event
, c
);
2330 return log_error_errno(r
, "Failed to add defer event source: %m");
2337 static int run(int argc
, char *argv
[]) {
2338 bool need_seek
= false, since_seeked
= false, use_cursor
= false, after_cursor
= false;
2339 _cleanup_(loop_device_unrefp
) LoopDevice
*loop_device
= NULL
;
2340 _cleanup_(umount_and_freep
) char *mounted_dir
= NULL
;
2341 _cleanup_(sd_journal_closep
) sd_journal
*j
= NULL
;
2342 _cleanup_close_
int machine_fd
= -EBADF
;
2343 int n_shown
, r
, poll_fd
= -EBADF
;
2345 setlocale(LC_ALL
, "");
2348 /* Increase max number of open files if we can, we might needs this when browsing journal files, which might be
2349 * split up into many files. */
2350 (void) rlimit_nofile_bump(HIGH_RLIMIT_NOFILE
);
2352 r
= parse_argv(argc
, argv
);
2359 r
= mount_image_privately_interactively(
2362 DISSECT_IMAGE_GENERIC_ROOT
|
2363 DISSECT_IMAGE_REQUIRE_ROOT
|
2364 DISSECT_IMAGE_VALIDATE_OS
|
2365 DISSECT_IMAGE_RELAX_VAR_CHECK
|
2366 (arg_action
== ACTION_UPDATE_CATALOG
? DISSECT_IMAGE_FSCK
|DISSECT_IMAGE_GROWFS
: DISSECT_IMAGE_READ_ONLY
),
2368 /* ret_dir_fd= */ NULL
,
2373 arg_root
= strdup(mounted_dir
);
2378 signal(SIGWINCH
, columns_lines_cache_reset
);
2381 switch (arg_action
) {
2383 case ACTION_NEW_ID128
:
2384 return id128_print_new(ID128_PRINT_PRETTY
);
2386 case ACTION_SETUP_KEYS
:
2387 return setup_keys();
2389 case ACTION_LIST_CATALOG
:
2390 case ACTION_DUMP_CATALOG
:
2391 case ACTION_UPDATE_CATALOG
: {
2392 _cleanup_free_
char *database
= NULL
;
2394 database
= path_join(arg_root
, CATALOG_DATABASE
);
2398 if (arg_action
== ACTION_UPDATE_CATALOG
) {
2399 r
= catalog_update(database
, arg_root
, catalog_file_dirs
);
2401 return log_error_errno(r
, "Failed to list catalog: %m");
2403 bool oneline
= arg_action
== ACTION_LIST_CATALOG
;
2405 pager_open(arg_pager_flags
);
2408 r
= catalog_list_items(stdout
, database
, oneline
, argv
+ optind
);
2410 r
= catalog_list(stdout
, database
, oneline
);
2412 return log_error_errno(r
, "Failed to list catalog: %m");
2419 return flush_to_var();
2421 case ACTION_RELINQUISH_VAR
:
2422 return relinquish_var();
2425 return sync_journal();
2431 case ACTION_PRINT_HEADER
:
2433 case ACTION_DISK_USAGE
:
2434 case ACTION_LIST_BOOTS
:
2436 case ACTION_ROTATE_AND_VACUUM
:
2437 case ACTION_LIST_FIELDS
:
2438 case ACTION_LIST_FIELD_NAMES
:
2439 /* These ones require access to the journal files, continue below. */
2443 assert_not_reached();
2447 r
= sd_journal_open_directory(&j
, arg_directory
, arg_journal_type
);
2449 r
= sd_journal_open_directory(&j
, arg_root
, arg_journal_type
| SD_JOURNAL_OS_ROOT
);
2450 else if (arg_file_stdin
)
2451 r
= sd_journal_open_files_fd(&j
, (int[]) { STDIN_FILENO
}, 1, 0);
2453 r
= sd_journal_open_files(&j
, (const char**) arg_file
, 0);
2454 else if (arg_machine
) {
2455 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2456 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2457 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*bus
= NULL
;
2461 /* The file descriptor returned by OpenMachineRootDirectory() will be owned by users/groups of
2462 * the container, thus we need root privileges to override them. */
2463 return log_error_errno(SYNTHETIC_ERRNO(EPERM
), "Using the --machine= switch requires root privileges.");
2465 r
= sd_bus_open_system(&bus
);
2467 return log_error_errno(r
, "Failed to open system bus: %m");
2469 r
= bus_call_method(bus
, bus_machine_mgr
, "OpenMachineRootDirectory", &error
, &reply
, "s", arg_machine
);
2471 return log_error_errno(r
, "Failed to open root directory: %s", bus_error_message(&error
, r
));
2473 r
= sd_bus_message_read(reply
, "h", &fd
);
2475 return bus_log_parse_error(r
);
2477 machine_fd
= fcntl(fd
, F_DUPFD_CLOEXEC
, 3);
2479 return log_error_errno(errno
, "Failed to duplicate file descriptor: %m");
2481 r
= sd_journal_open_directory_fd(&j
, machine_fd
, SD_JOURNAL_OS_ROOT
);
2483 r
= sd_journal_open_namespace(
2486 (arg_merge
? 0 : SD_JOURNAL_LOCAL_ONLY
) |
2487 arg_namespace_flags
| arg_journal_type
);
2489 return log_error_errno(r
, "Failed to open %s: %m", arg_directory
?: arg_file
? "files" : "journal");
2491 r
= journal_access_check_and_warn(j
, arg_quiet
,
2492 !(arg_journal_type
== SD_JOURNAL_CURRENT_USER
|| arg_user_units
));
2496 switch (arg_action
) {
2498 case ACTION_NEW_ID128
:
2499 case ACTION_SETUP_KEYS
:
2500 case ACTION_LIST_CATALOG
:
2501 case ACTION_DUMP_CATALOG
:
2502 case ACTION_UPDATE_CATALOG
:
2506 assert_not_reached();
2508 case ACTION_PRINT_HEADER
:
2509 journal_print_header(j
);
2513 return verify(j
, !arg_quiet
);
2515 case ACTION_DISK_USAGE
: {
2518 r
= sd_journal_get_usage(j
, &bytes
);
2522 printf("Archived and active journals take up %s in the file system.\n",
2523 FORMAT_BYTES(bytes
));
2528 case ACTION_LIST_BOOTS
:
2529 return list_boots(j
);
2531 case ACTION_ROTATE_AND_VACUUM
:
2539 case ACTION_VACUUM
: {
2543 HASHMAP_FOREACH(d
, j
->directories_by_path
) {
2544 r
= journal_directory_vacuum(d
->path
, arg_vacuum_size
, arg_vacuum_n_files
, arg_vacuum_time
, NULL
, !arg_quiet
);
2546 log_error_errno(r
, "Failed to vacuum %s: %m", d
->path
);
2555 case ACTION_LIST_FIELD_NAMES
: {
2558 SD_JOURNAL_FOREACH_FIELD(j
, field
)
2559 printf("%s\n", field
);
2565 case ACTION_LIST_FIELDS
:
2569 assert_not_reached();
2572 if (arg_boot_offset
!= 0 &&
2573 sd_journal_has_runtime_files(j
) > 0 &&
2574 sd_journal_has_persistent_files(j
) == 0) {
2575 log_info("Specifying boot ID or boot offset has no effect, no persistent journal was found.");
2577 if (arg_action
== ACTION_SHOW
&& arg_compiled_pattern
)
2582 /* add_boot() must be called first!
2583 * It may need to seek the journal to find parent boot IDs. */
2594 return log_error_errno(r
, "Failed to add filter for units: %m");
2596 r
= add_syslog_identifier(j
);
2598 return log_error_errno(r
, "Failed to add filter for syslog identifiers: %m");
2600 r
= add_priorities(j
);
2604 r
= add_facilities(j
);
2608 r
= add_matches(j
, argv
+ optind
);
2612 if (DEBUG_LOGGING
) {
2613 _cleanup_free_
char *filter
= NULL
;
2615 filter
= journal_make_match_string(j
);
2619 log_debug("Journal filter: %s", filter
);
2622 if (arg_action
== ACTION_LIST_FIELDS
)
2623 return action_list_fields(j
);
2625 /* Opening the fd now means the first sd_journal_wait() will actually wait */
2627 poll_fd
= sd_journal_get_fd(j
);
2628 if (poll_fd
== -EMFILE
) {
2629 log_warning_errno(poll_fd
, "Insufficient watch descriptors available. Reverting to -n.");
2631 } else if (poll_fd
== -EMEDIUMTYPE
)
2632 return log_error_errno(poll_fd
, "The --follow switch is not supported in conjunction with reading from STDIN.");
2633 else if (poll_fd
< 0)
2634 return log_error_errno(poll_fd
, "Failed to get journal fd: %m");
2637 if (arg_cursor
|| arg_after_cursor
|| arg_cursor_file
) {
2638 _cleanup_free_
char *cursor_from_file
= NULL
;
2639 const char *cursor
= arg_cursor
?: arg_after_cursor
;
2641 if (arg_cursor_file
) {
2642 r
= read_one_line_file(arg_cursor_file
, &cursor_from_file
);
2643 if (r
< 0 && r
!= -ENOENT
)
2644 return log_error_errno(r
, "Failed to read cursor file %s: %m", arg_cursor_file
);
2647 cursor
= cursor_from_file
;
2648 after_cursor
= true;
2651 after_cursor
= arg_after_cursor
;
2654 r
= sd_journal_seek_cursor(j
, cursor
);
2656 return log_error_errno(r
, "Failed to seek to cursor: %m");
2664 r
= sd_journal_next_skip(j
, 1 + after_cursor
);
2666 r
= sd_journal_previous_skip(j
, 1 + after_cursor
);
2668 if (after_cursor
&& r
< 2) {
2669 /* We couldn't find the next entry after the cursor. */
2676 } else if (arg_until_set
&& (arg_reverse
|| arg_lines
>= 0)) {
2677 /* If both --until and any of --reverse and --lines is specified, things get
2678 * a little tricky. We seek to the place of --until first. If only --reverse or
2679 * --reverse and --lines is specified, we search backwards and let the output
2680 * counter handle --lines for us. If only --lines is used, we just jump backwards
2681 * arg_lines and search afterwards from there. */
2683 r
= sd_journal_seek_realtime_usec(j
, arg_until
);
2685 return log_error_errno(r
, "Failed to seek to date: %m");
2688 r
= sd_journal_previous(j
);
2689 else /* arg_lines >= 0 */
2690 r
= sd_journal_previous_skip(j
, arg_lines
);
2692 } else if (arg_reverse
) {
2693 r
= sd_journal_seek_tail(j
);
2695 return log_error_errno(r
, "Failed to seek to tail: %m");
2697 r
= sd_journal_previous(j
);
2699 } else if (arg_lines
>= 0) {
2700 r
= sd_journal_seek_tail(j
);
2702 return log_error_errno(r
, "Failed to seek to tail: %m");
2704 r
= sd_journal_previous_skip(j
, arg_lines
);
2706 } else if (arg_since_set
) {
2707 /* This is placed after arg_reverse and arg_lines. If --since is used without
2708 * both, we seek to the place of --since and search afterwards from there.
2709 * If used with --reverse or --lines, we seek to the tail first and check if
2710 * the entry is within the range of --since later. */
2712 r
= sd_journal_seek_realtime_usec(j
, arg_since
);
2714 return log_error_errno(r
, "Failed to seek to date: %m");
2715 since_seeked
= true;
2717 r
= sd_journal_next(j
);
2720 r
= sd_journal_seek_head(j
);
2722 return log_error_errno(r
, "Failed to seek to head: %m");
2724 r
= sd_journal_next(j
);
2727 return log_error_errno(r
, "Failed to iterate through journal: %m");
2732 pager_open(arg_pager_flags
);
2734 if (!arg_quiet
&& (arg_lines
!= 0 || arg_follow
) && DEBUG_LOGGING
) {
2736 char start_buf
[FORMAT_TIMESTAMP_MAX
], end_buf
[FORMAT_TIMESTAMP_MAX
];
2738 r
= sd_journal_get_cutoff_realtime_usec(j
, &start
, &end
);
2740 return log_error_errno(r
, "Failed to get cutoff: %m");
2743 printf("-- Journal begins at %s. --\n",
2744 format_timestamp_maybe_utc(start_buf
, sizeof(start_buf
), start
));
2746 printf("-- Journal begins at %s, ends at %s. --\n",
2747 format_timestamp_maybe_utc(start_buf
, sizeof(start_buf
), start
),
2748 format_timestamp_maybe_utc(end_buf
, sizeof(end_buf
), end
));
2754 .need_seek
= need_seek
,
2755 .since_seeked
= since_seeked
,
2759 _cleanup_(sd_event_unrefp
) sd_event
*e
= NULL
;
2762 assert(poll_fd
>= 0);
2764 r
= setup_event(&c
, poll_fd
, &e
);
2768 r
= sd_event_loop(e
);
2773 /* unref signal event sources. */
2774 e
= sd_event_unref(e
);
2776 r
= update_cursor(j
);
2780 /* re-send the original signal. */
2781 assert(SIGNAL_VALID(sig
));
2783 log_error("Failed to raise the original signal SIG%s, ignoring: %m", signal_to_string(sig
));
2793 if (n_shown
== 0 && !arg_quiet
)
2794 printf("-- No entries --\n");
2796 r
= update_cursor(j
);
2800 if (arg_compiled_pattern
&& n_shown
== 0)
2801 /* --grep was used, no error was thrown, but the pattern didn't
2802 * match anything. Let's mimic grep's behavior here and return
2803 * a non-zero exit code, so journalctl --grep can be used
2804 * in scripts and such */
2810 DEFINE_MAIN_FUNCTION(run
);