]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/journal/journalctl.c
tree-wide: use -EBADF for fd initialization
[thirdparty/systemd.git] / src / journal / journalctl.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <errno.h>
4 #include <fcntl.h>
5 #include <fnmatch.h>
6 #include <getopt.h>
7 #include <linux/fs.h>
8 #include <signal.h>
9 #include <stddef.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <sys/inotify.h>
13 #include <sys/stat.h>
14 #include <unistd.h>
15
16 #include "sd-bus.h"
17 #include "sd-device.h"
18 #include "sd-journal.h"
19
20 #include "acl-util.h"
21 #include "alloc-util.h"
22 #include "build.h"
23 #include "bus-error.h"
24 #include "bus-util.h"
25 #include "catalog.h"
26 #include "chase-symlinks.h"
27 #include "chattr-util.h"
28 #include "constants.h"
29 #include "dissect-image.h"
30 #include "fd-util.h"
31 #include "fileio.h"
32 #include "format-table.h"
33 #include "format-util.h"
34 #include "fs-util.h"
35 #include "fsprg.h"
36 #include "glob-util.h"
37 #include "hostname-util.h"
38 #include "id128-print.h"
39 #include "io-util.h"
40 #include "journal-def.h"
41 #include "journal-internal.h"
42 #include "journal-util.h"
43 #include "journal-vacuum.h"
44 #include "journal-verify.h"
45 #include "locale-util.h"
46 #include "log.h"
47 #include "logs-show.h"
48 #include "memory-util.h"
49 #include "mkdir.h"
50 #include "mount-util.h"
51 #include "mountpoint-util.h"
52 #include "nulstr-util.h"
53 #include "pager.h"
54 #include "parse-argument.h"
55 #include "parse-util.h"
56 #include "path-util.h"
57 #include "pcre2-util.h"
58 #include "pretty-print.h"
59 #include "qrcode-util.h"
60 #include "random-util.h"
61 #include "rlimit-util.h"
62 #include "set.h"
63 #include "sigbus.h"
64 #include "static-destruct.h"
65 #include "stdio-util.h"
66 #include "string-table.h"
67 #include "strv.h"
68 #include "syslog-util.h"
69 #include "terminal-util.h"
70 #include "tmpfile-util.h"
71 #include "unit-name.h"
72 #include "user-util.h"
73 #include "varlink.h"
74
75 #define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
76 #define PROCESS_INOTIFY_INTERVAL 1024 /* Every 1,024 messages processed */
77
78 enum {
79 /* Special values for arg_lines */
80 ARG_LINES_DEFAULT = -2,
81 ARG_LINES_ALL = -1,
82 };
83
84 static OutputMode arg_output = OUTPUT_SHORT;
85 static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
86 static bool arg_utc = false;
87 static bool arg_follow = false;
88 static bool arg_full = true;
89 static bool arg_all = false;
90 static PagerFlags arg_pager_flags = 0;
91 static int arg_lines = ARG_LINES_DEFAULT;
92 static bool arg_no_tail = false;
93 static bool arg_quiet = false;
94 static bool arg_merge = false;
95 static bool arg_boot = false;
96 static sd_id128_t arg_boot_id = {};
97 static int arg_boot_offset = 0;
98 static bool arg_dmesg = false;
99 static bool arg_no_hostname = false;
100 static const char *arg_cursor = NULL;
101 static const char *arg_cursor_file = NULL;
102 static const char *arg_after_cursor = NULL;
103 static bool arg_show_cursor = false;
104 static const char *arg_directory = NULL;
105 static char **arg_file = NULL;
106 static bool arg_file_stdin = false;
107 static int arg_priorities = 0xFF;
108 static Set *arg_facilities = NULL;
109 static char *arg_verify_key = NULL;
110 #if HAVE_GCRYPT
111 static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC;
112 static bool arg_force = false;
113 #endif
114 static usec_t arg_since, arg_until;
115 static bool arg_since_set = false, arg_until_set = false;
116 static char **arg_syslog_identifier = NULL;
117 static char **arg_system_units = NULL;
118 static char **arg_user_units = NULL;
119 static const char *arg_field = NULL;
120 static bool arg_catalog = false;
121 static bool arg_reverse = false;
122 static int arg_journal_type = 0;
123 static int arg_namespace_flags = 0;
124 static char *arg_root = NULL;
125 static char *arg_image = NULL;
126 static const char *arg_machine = NULL;
127 static const char *arg_namespace = NULL;
128 static uint64_t arg_vacuum_size = 0;
129 static uint64_t arg_vacuum_n_files = 0;
130 static usec_t arg_vacuum_time = 0;
131 static char **arg_output_fields = NULL;
132 static const char *arg_pattern = NULL;
133 static pcre2_code *arg_compiled_pattern = NULL;
134 static PatternCompileCase arg_case = PATTERN_COMPILE_CASE_AUTO;
135
136 STATIC_DESTRUCTOR_REGISTER(arg_file, strv_freep);
137 STATIC_DESTRUCTOR_REGISTER(arg_facilities, set_freep);
138 STATIC_DESTRUCTOR_REGISTER(arg_verify_key, freep);
139 STATIC_DESTRUCTOR_REGISTER(arg_syslog_identifier, strv_freep);
140 STATIC_DESTRUCTOR_REGISTER(arg_system_units, strv_freep);
141 STATIC_DESTRUCTOR_REGISTER(arg_user_units, strv_freep);
142 STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
143 STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
144 STATIC_DESTRUCTOR_REGISTER(arg_output_fields, strv_freep);
145 STATIC_DESTRUCTOR_REGISTER(arg_compiled_pattern, pattern_freep);
146
147 static enum {
148 ACTION_SHOW,
149 ACTION_NEW_ID128,
150 ACTION_PRINT_HEADER,
151 ACTION_SETUP_KEYS,
152 ACTION_VERIFY,
153 ACTION_DISK_USAGE,
154 ACTION_LIST_CATALOG,
155 ACTION_DUMP_CATALOG,
156 ACTION_UPDATE_CATALOG,
157 ACTION_LIST_BOOTS,
158 ACTION_FLUSH,
159 ACTION_RELINQUISH_VAR,
160 ACTION_SYNC,
161 ACTION_ROTATE,
162 ACTION_VACUUM,
163 ACTION_ROTATE_AND_VACUUM,
164 ACTION_LIST_FIELDS,
165 ACTION_LIST_FIELD_NAMES,
166 } arg_action = ACTION_SHOW;
167
168 typedef struct BootId {
169 sd_id128_t id;
170 uint64_t first;
171 uint64_t last;
172 LIST_FIELDS(struct BootId, boot_list);
173 } BootId;
174
175 static int add_matches_for_device(sd_journal *j, const char *devpath) {
176 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
177 sd_device *d = NULL;
178 struct stat st;
179 int r;
180
181 assert(j);
182 assert(devpath);
183
184 if (!path_startswith(devpath, "/dev/"))
185 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
186 "Devpath does not start with /dev/");
187
188 if (stat(devpath, &st) < 0)
189 return log_error_errno(errno, "Couldn't stat file: %m");
190
191 r = sd_device_new_from_stat_rdev(&device, &st);
192 if (r < 0)
193 return log_error_errno(r, "Failed to get device from devnum %u:%u: %m", major(st.st_rdev), minor(st.st_rdev));
194
195 for (d = device; d; ) {
196 _cleanup_free_ char *match = NULL;
197 const char *subsys, *sysname, *devnode;
198 sd_device *parent;
199
200 r = sd_device_get_subsystem(d, &subsys);
201 if (r < 0)
202 goto get_parent;
203
204 r = sd_device_get_sysname(d, &sysname);
205 if (r < 0)
206 goto get_parent;
207
208 match = strjoin("_KERNEL_DEVICE=+", subsys, ":", sysname);
209 if (!match)
210 return log_oom();
211
212 r = sd_journal_add_match(j, match, 0);
213 if (r < 0)
214 return log_error_errno(r, "Failed to add match: %m");
215
216 if (sd_device_get_devname(d, &devnode) >= 0) {
217 _cleanup_free_ char *match1 = NULL;
218
219 r = stat(devnode, &st);
220 if (r < 0)
221 return log_error_errno(r, "Failed to stat() device node \"%s\": %m", devnode);
222
223 r = asprintf(&match1, "_KERNEL_DEVICE=%c%u:%u", S_ISBLK(st.st_mode) ? 'b' : 'c', major(st.st_rdev), minor(st.st_rdev));
224 if (r < 0)
225 return log_oom();
226
227 r = sd_journal_add_match(j, match1, 0);
228 if (r < 0)
229 return log_error_errno(r, "Failed to add match: %m");
230 }
231
232 get_parent:
233 if (sd_device_get_parent(d, &parent) < 0)
234 break;
235
236 d = parent;
237 }
238
239 r = add_match_this_boot(j, arg_machine);
240 if (r < 0)
241 return log_error_errno(r, "Failed to add match for the current boot: %m");
242
243 return 0;
244 }
245
246 static char *format_timestamp_maybe_utc(char *buf, size_t l, usec_t t) {
247
248 if (arg_utc)
249 return format_timestamp_style(buf, l, t, TIMESTAMP_UTC);
250
251 return format_timestamp(buf, l, t);
252 }
253
254 static int parse_boot_descriptor(const char *x, sd_id128_t *boot_id, int *offset) {
255 sd_id128_t id = SD_ID128_NULL;
256 int off = 0, r;
257
258 if (streq(x, "all")) {
259 *boot_id = SD_ID128_NULL;
260 *offset = 0;
261 return 0;
262 } else if (strlen(x) >= SD_ID128_STRING_MAX - 1) {
263 char *t;
264
265 t = strndupa_safe(x, SD_ID128_STRING_MAX - 1);
266 r = sd_id128_from_string(t, &id);
267 if (r >= 0)
268 x += SD_ID128_STRING_MAX - 1;
269
270 if (!IN_SET(*x, 0, '-', '+'))
271 return -EINVAL;
272
273 if (*x != 0) {
274 r = safe_atoi(x, &off);
275 if (r < 0)
276 return r;
277 }
278 } else {
279 r = safe_atoi(x, &off);
280 if (r < 0)
281 return r;
282 }
283
284 if (boot_id)
285 *boot_id = id;
286
287 if (offset)
288 *offset = off;
289
290 return 1;
291 }
292
293 static int help_facilities(void) {
294 if (!arg_quiet)
295 puts("Available facilities:");
296
297 for (int i = 0; i < LOG_NFACILITIES; i++) {
298 _cleanup_free_ char *t = NULL;
299
300 if (log_facility_unshifted_to_string_alloc(i, &t))
301 return log_oom();
302 puts(t);
303 }
304
305 return 0;
306 }
307
308 static int help(void) {
309 _cleanup_free_ char *link = NULL;
310 int r;
311
312 pager_open(arg_pager_flags);
313
314 r = terminal_urlify_man("journalctl", "1", &link);
315 if (r < 0)
316 return log_oom();
317
318 printf("%1$s [OPTIONS...] [MATCHES...]\n\n"
319 "%5$sQuery the journal.%6$s\n\n"
320 "%3$sSource Options:%4$s\n"
321 " --system Show the system journal\n"
322 " --user Show the user journal for the current user\n"
323 " -M --machine=CONTAINER Operate on local container\n"
324 " -m --merge Show entries from all available journals\n"
325 " -D --directory=PATH Show journal files from directory\n"
326 " --file=PATH Show journal file\n"
327 " --root=ROOT Operate on files below a root directory\n"
328 " --image=IMAGE Operate on files in filesystem image\n"
329 " --namespace=NAMESPACE Show journal data from specified journal namespace\n"
330 "\n%3$sFiltering Options:%4$s\n"
331 " -S --since=DATE Show entries not older than the specified date\n"
332 " -U --until=DATE Show entries not newer than the specified date\n"
333 " -c --cursor=CURSOR Show entries starting at the specified cursor\n"
334 " --after-cursor=CURSOR Show entries after the specified cursor\n"
335 " --cursor-file=FILE Show entries after cursor in FILE and update FILE\n"
336 " -b --boot[=ID] Show current boot or the specified boot\n"
337 " -u --unit=UNIT Show logs from the specified unit\n"
338 " --user-unit=UNIT Show logs from the specified user unit\n"
339 " -t --identifier=STRING Show entries with the specified syslog identifier\n"
340 " -p --priority=RANGE Show entries with the specified priority\n"
341 " --facility=FACILITY... Show entries with the specified facilities\n"
342 " -g --grep=PATTERN Show entries with MESSAGE matching PATTERN\n"
343 " --case-sensitive[=BOOL] Force case sensitive or insensitive matching\n"
344 " -k --dmesg Show kernel message log from the current boot\n"
345 "\n%3$sOutput Control Options:%4$s\n"
346 " -o --output=STRING Change journal output mode (short, short-precise,\n"
347 " short-iso, short-iso-precise, short-full,\n"
348 " short-monotonic, short-unix, verbose, export,\n"
349 " json, json-pretty, json-sse, json-seq, cat,\n"
350 " with-unit)\n"
351 " --output-fields=LIST Select fields to print in verbose/export/json modes\n"
352 " -n --lines[=INTEGER] Number of journal entries to show\n"
353 " -r --reverse Show the newest entries first\n"
354 " --show-cursor Print the cursor after all the entries\n"
355 " --utc Express time in Coordinated Universal Time (UTC)\n"
356 " -x --catalog Add message explanations where available\n"
357 " --no-hostname Suppress output of hostname field\n"
358 " --no-full Ellipsize fields\n"
359 " -a --all Show all fields, including long and unprintable\n"
360 " -f --follow Follow the journal\n"
361 " --no-tail Show all lines, even in follow mode\n"
362 " -q --quiet Do not show info messages and privilege warning\n"
363 "\n%3$sPager Control Options:%4$s\n"
364 " --no-pager Do not pipe output into a pager\n"
365 " -e --pager-end Immediately jump to the end in the pager\n"
366 "\n%3$sForward Secure Sealing (FSS) Options:%4$s\n"
367 " --interval=TIME Time interval for changing the FSS sealing key\n"
368 " --verify-key=KEY Specify FSS verification key\n"
369 " --force Override of the FSS key pair with --setup-keys\n"
370 "\n%3$sCommands:%4$s\n"
371 " -h --help Show this help text\n"
372 " --version Show package version\n"
373 " -N --fields List all field names currently used\n"
374 " -F --field=FIELD List all values that a specified field takes\n"
375 " --list-boots Show terse information about recorded boots\n"
376 " --disk-usage Show total disk usage of all journal files\n"
377 " --vacuum-size=BYTES Reduce disk usage below specified size\n"
378 " --vacuum-files=INT Leave only the specified number of journal files\n"
379 " --vacuum-time=TIME Remove journal files older than specified time\n"
380 " --verify Verify journal file consistency\n"
381 " --sync Synchronize unwritten journal messages to disk\n"
382 " --relinquish-var Stop logging to disk, log to temporary file system\n"
383 " --smart-relinquish-var Similar, but NOP if log directory is on root mount\n"
384 " --flush Flush all journal data from /run into /var\n"
385 " --rotate Request immediate rotation of the journal files\n"
386 " --header Show journal header information\n"
387 " --list-catalog Show all message IDs in the catalog\n"
388 " --dump-catalog Show entries in the message catalog\n"
389 " --update-catalog Update the message catalog database\n"
390 " --setup-keys Generate a new FSS key pair\n"
391 "\nSee the %2$s for details.\n",
392 program_invocation_short_name,
393 link,
394 ansi_underline(),
395 ansi_normal(),
396 ansi_highlight(),
397 ansi_normal());
398
399 return 0;
400 }
401
402 static int parse_argv(int argc, char *argv[]) {
403
404 enum {
405 ARG_VERSION = 0x100,
406 ARG_NO_PAGER,
407 ARG_NO_FULL,
408 ARG_NO_TAIL,
409 ARG_NEW_ID128,
410 ARG_THIS_BOOT,
411 ARG_LIST_BOOTS,
412 ARG_USER,
413 ARG_SYSTEM,
414 ARG_ROOT,
415 ARG_IMAGE,
416 ARG_HEADER,
417 ARG_FACILITY,
418 ARG_SETUP_KEYS,
419 ARG_FILE,
420 ARG_INTERVAL,
421 ARG_VERIFY,
422 ARG_VERIFY_KEY,
423 ARG_DISK_USAGE,
424 ARG_AFTER_CURSOR,
425 ARG_CURSOR_FILE,
426 ARG_SHOW_CURSOR,
427 ARG_USER_UNIT,
428 ARG_LIST_CATALOG,
429 ARG_DUMP_CATALOG,
430 ARG_UPDATE_CATALOG,
431 ARG_FORCE,
432 ARG_CASE_SENSITIVE,
433 ARG_UTC,
434 ARG_SYNC,
435 ARG_FLUSH,
436 ARG_RELINQUISH_VAR,
437 ARG_SMART_RELINQUISH_VAR,
438 ARG_ROTATE,
439 ARG_VACUUM_SIZE,
440 ARG_VACUUM_FILES,
441 ARG_VACUUM_TIME,
442 ARG_NO_HOSTNAME,
443 ARG_OUTPUT_FIELDS,
444 ARG_NAMESPACE,
445 };
446
447 static const struct option options[] = {
448 { "help", no_argument, NULL, 'h' },
449 { "version" , no_argument, NULL, ARG_VERSION },
450 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
451 { "pager-end", no_argument, NULL, 'e' },
452 { "follow", no_argument, NULL, 'f' },
453 { "force", no_argument, NULL, ARG_FORCE },
454 { "output", required_argument, NULL, 'o' },
455 { "all", no_argument, NULL, 'a' },
456 { "full", no_argument, NULL, 'l' },
457 { "no-full", no_argument, NULL, ARG_NO_FULL },
458 { "lines", optional_argument, NULL, 'n' },
459 { "no-tail", no_argument, NULL, ARG_NO_TAIL },
460 { "new-id128", no_argument, NULL, ARG_NEW_ID128 }, /* deprecated */
461 { "quiet", no_argument, NULL, 'q' },
462 { "merge", no_argument, NULL, 'm' },
463 { "this-boot", no_argument, NULL, ARG_THIS_BOOT }, /* deprecated */
464 { "boot", optional_argument, NULL, 'b' },
465 { "list-boots", no_argument, NULL, ARG_LIST_BOOTS },
466 { "dmesg", no_argument, NULL, 'k' },
467 { "system", no_argument, NULL, ARG_SYSTEM },
468 { "user", no_argument, NULL, ARG_USER },
469 { "directory", required_argument, NULL, 'D' },
470 { "file", required_argument, NULL, ARG_FILE },
471 { "root", required_argument, NULL, ARG_ROOT },
472 { "image", required_argument, NULL, ARG_IMAGE },
473 { "header", no_argument, NULL, ARG_HEADER },
474 { "identifier", required_argument, NULL, 't' },
475 { "priority", required_argument, NULL, 'p' },
476 { "facility", required_argument, NULL, ARG_FACILITY },
477 { "grep", required_argument, NULL, 'g' },
478 { "case-sensitive", optional_argument, NULL, ARG_CASE_SENSITIVE },
479 { "setup-keys", no_argument, NULL, ARG_SETUP_KEYS },
480 { "interval", required_argument, NULL, ARG_INTERVAL },
481 { "verify", no_argument, NULL, ARG_VERIFY },
482 { "verify-key", required_argument, NULL, ARG_VERIFY_KEY },
483 { "disk-usage", no_argument, NULL, ARG_DISK_USAGE },
484 { "cursor", required_argument, NULL, 'c' },
485 { "cursor-file", required_argument, NULL, ARG_CURSOR_FILE },
486 { "after-cursor", required_argument, NULL, ARG_AFTER_CURSOR },
487 { "show-cursor", no_argument, NULL, ARG_SHOW_CURSOR },
488 { "since", required_argument, NULL, 'S' },
489 { "until", required_argument, NULL, 'U' },
490 { "unit", required_argument, NULL, 'u' },
491 { "user-unit", required_argument, NULL, ARG_USER_UNIT },
492 { "field", required_argument, NULL, 'F' },
493 { "fields", no_argument, NULL, 'N' },
494 { "catalog", no_argument, NULL, 'x' },
495 { "list-catalog", no_argument, NULL, ARG_LIST_CATALOG },
496 { "dump-catalog", no_argument, NULL, ARG_DUMP_CATALOG },
497 { "update-catalog", no_argument, NULL, ARG_UPDATE_CATALOG },
498 { "reverse", no_argument, NULL, 'r' },
499 { "machine", required_argument, NULL, 'M' },
500 { "utc", no_argument, NULL, ARG_UTC },
501 { "flush", no_argument, NULL, ARG_FLUSH },
502 { "relinquish-var", no_argument, NULL, ARG_RELINQUISH_VAR },
503 { "smart-relinquish-var", no_argument, NULL, ARG_SMART_RELINQUISH_VAR },
504 { "sync", no_argument, NULL, ARG_SYNC },
505 { "rotate", no_argument, NULL, ARG_ROTATE },
506 { "vacuum-size", required_argument, NULL, ARG_VACUUM_SIZE },
507 { "vacuum-files", required_argument, NULL, ARG_VACUUM_FILES },
508 { "vacuum-time", required_argument, NULL, ARG_VACUUM_TIME },
509 { "no-hostname", no_argument, NULL, ARG_NO_HOSTNAME },
510 { "output-fields", required_argument, NULL, ARG_OUTPUT_FIELDS },
511 { "namespace", required_argument, NULL, ARG_NAMESPACE },
512 {}
513 };
514
515 int c, r;
516
517 assert(argc >= 0);
518 assert(argv);
519
520 while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:g:c:S:U:t:u:NF:xrM:", options, NULL)) >= 0)
521
522 switch (c) {
523
524 case 'h':
525 return help();
526
527 case ARG_VERSION:
528 return version();
529
530 case ARG_NO_PAGER:
531 arg_pager_flags |= PAGER_DISABLE;
532 break;
533
534 case 'e':
535 arg_pager_flags |= PAGER_JUMP_TO_END;
536
537 if (arg_lines == ARG_LINES_DEFAULT)
538 arg_lines = 1000;
539
540 arg_boot = true;
541
542 break;
543
544 case 'f':
545 arg_follow = true;
546
547 arg_boot = true;
548 arg_boot_id = SD_ID128_NULL;
549 arg_boot_offset = 0;
550
551 break;
552
553 case 'o':
554 if (streq(optarg, "help")) {
555 DUMP_STRING_TABLE(output_mode, OutputMode, _OUTPUT_MODE_MAX);
556 return 0;
557 }
558
559 arg_output = output_mode_from_string(optarg);
560 if (arg_output < 0)
561 return log_error_errno(arg_output, "Unknown output format '%s'.", optarg);
562
563 if (IN_SET(arg_output, OUTPUT_EXPORT, OUTPUT_JSON, OUTPUT_JSON_PRETTY, OUTPUT_JSON_SSE, OUTPUT_JSON_SEQ, OUTPUT_CAT))
564 arg_quiet = true;
565
566 if (OUTPUT_MODE_IS_JSON(arg_output))
567 arg_json_format_flags = output_mode_to_json_format_flags(arg_output) | JSON_FORMAT_COLOR_AUTO;
568 else
569 arg_json_format_flags = JSON_FORMAT_OFF;
570
571 break;
572
573 case 'l':
574 arg_full = true;
575 break;
576
577 case ARG_NO_FULL:
578 arg_full = false;
579 break;
580
581 case 'a':
582 arg_all = true;
583 break;
584
585 case 'n':
586 if (optarg) {
587 if (streq(optarg, "all"))
588 arg_lines = ARG_LINES_ALL;
589 else {
590 r = safe_atoi(optarg, &arg_lines);
591 if (r < 0 || arg_lines < 0)
592 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse lines '%s'", optarg);
593 }
594 } else {
595 arg_lines = 10;
596
597 /* Hmm, no argument? Maybe the next
598 * word on the command line is
599 * supposed to be the argument? Let's
600 * see if there is one, and is
601 * parsable. */
602 if (optind < argc) {
603 int n;
604 if (streq(argv[optind], "all")) {
605 arg_lines = ARG_LINES_ALL;
606 optind++;
607 } else if (safe_atoi(argv[optind], &n) >= 0 && n >= 0) {
608 arg_lines = n;
609 optind++;
610 }
611 }
612 }
613
614 break;
615
616 case ARG_NO_TAIL:
617 arg_no_tail = true;
618 break;
619
620 case ARG_NEW_ID128:
621 arg_action = ACTION_NEW_ID128;
622 break;
623
624 case 'q':
625 arg_quiet = true;
626 break;
627
628 case 'm':
629 arg_merge = true;
630 break;
631
632 case ARG_THIS_BOOT:
633 arg_boot = true;
634 arg_boot_id = SD_ID128_NULL;
635 arg_boot_offset = 0;
636 break;
637
638 case 'b':
639 arg_boot = true;
640 arg_boot_id = SD_ID128_NULL;
641 arg_boot_offset = 0;
642
643 if (optarg) {
644 r = parse_boot_descriptor(optarg, &arg_boot_id, &arg_boot_offset);
645 if (r < 0)
646 return log_error_errno(r, "Failed to parse boot descriptor '%s'", optarg);
647
648 arg_boot = r;
649
650 /* Hmm, no argument? Maybe the next
651 * word on the command line is
652 * supposed to be the argument? Let's
653 * see if there is one and is parsable
654 * as a boot descriptor... */
655 } else if (optind < argc) {
656 r = parse_boot_descriptor(argv[optind], &arg_boot_id, &arg_boot_offset);
657 if (r >= 0) {
658 arg_boot = r;
659 optind++;
660 }
661 }
662 break;
663
664 case ARG_LIST_BOOTS:
665 arg_action = ACTION_LIST_BOOTS;
666 break;
667
668 case 'k':
669 arg_boot = arg_dmesg = true;
670 break;
671
672 case ARG_SYSTEM:
673 arg_journal_type |= SD_JOURNAL_SYSTEM;
674 break;
675
676 case ARG_USER:
677 arg_journal_type |= SD_JOURNAL_CURRENT_USER;
678 break;
679
680 case 'M':
681 arg_machine = optarg;
682 break;
683
684 case ARG_NAMESPACE:
685 if (streq(optarg, "*")) {
686 arg_namespace_flags = SD_JOURNAL_ALL_NAMESPACES;
687 arg_namespace = NULL;
688 } else if (startswith(optarg, "+")) {
689 arg_namespace_flags = SD_JOURNAL_INCLUDE_DEFAULT_NAMESPACE;
690 arg_namespace = optarg + 1;
691 } else if (isempty(optarg)) {
692 arg_namespace_flags = 0;
693 arg_namespace = NULL;
694 } else {
695 arg_namespace_flags = 0;
696 arg_namespace = optarg;
697 }
698
699 break;
700
701 case 'D':
702 arg_directory = optarg;
703 break;
704
705 case ARG_FILE:
706 if (streq(optarg, "-"))
707 /* An undocumented feature: we can read journal files from STDIN. We don't document
708 * this though, since after all we only support this for mmap-able, seekable files, and
709 * not for example pipes which are probably the primary usecase for reading things from
710 * STDIN. To avoid confusion we hence don't document this feature. */
711 arg_file_stdin = true;
712 else {
713 r = glob_extend(&arg_file, optarg, GLOB_NOCHECK);
714 if (r < 0)
715 return log_error_errno(r, "Failed to add paths: %m");
716 }
717 break;
718
719 case ARG_ROOT:
720 r = parse_path_argument(optarg, /* suppress_root= */ true, &arg_root);
721 if (r < 0)
722 return r;
723 break;
724
725 case ARG_IMAGE:
726 r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_image);
727 if (r < 0)
728 return r;
729 break;
730
731 case 'c':
732 arg_cursor = optarg;
733 break;
734
735 case ARG_CURSOR_FILE:
736 arg_cursor_file = optarg;
737 break;
738
739 case ARG_AFTER_CURSOR:
740 arg_after_cursor = optarg;
741 break;
742
743 case ARG_SHOW_CURSOR:
744 arg_show_cursor = true;
745 break;
746
747 case ARG_HEADER:
748 arg_action = ACTION_PRINT_HEADER;
749 break;
750
751 case ARG_VERIFY:
752 arg_action = ACTION_VERIFY;
753 break;
754
755 case ARG_DISK_USAGE:
756 arg_action = ACTION_DISK_USAGE;
757 break;
758
759 case ARG_VACUUM_SIZE:
760 r = parse_size(optarg, 1024, &arg_vacuum_size);
761 if (r < 0)
762 return log_error_errno(r, "Failed to parse vacuum size: %s", optarg);
763
764 arg_action = arg_action == ACTION_ROTATE ? ACTION_ROTATE_AND_VACUUM : ACTION_VACUUM;
765 break;
766
767 case ARG_VACUUM_FILES:
768 r = safe_atou64(optarg, &arg_vacuum_n_files);
769 if (r < 0)
770 return log_error_errno(r, "Failed to parse vacuum files: %s", optarg);
771
772 arg_action = arg_action == ACTION_ROTATE ? ACTION_ROTATE_AND_VACUUM : ACTION_VACUUM;
773 break;
774
775 case ARG_VACUUM_TIME:
776 r = parse_sec(optarg, &arg_vacuum_time);
777 if (r < 0)
778 return log_error_errno(r, "Failed to parse vacuum time: %s", optarg);
779
780 arg_action = arg_action == ACTION_ROTATE ? ACTION_ROTATE_AND_VACUUM : ACTION_VACUUM;
781 break;
782
783 #if HAVE_GCRYPT
784 case ARG_FORCE:
785 arg_force = true;
786 break;
787
788 case ARG_SETUP_KEYS:
789 arg_action = ACTION_SETUP_KEYS;
790 break;
791
792 case ARG_VERIFY_KEY:
793 r = free_and_strdup(&arg_verify_key, optarg);
794 if (r < 0)
795 return r;
796 /* Use memset not explicit_bzero() or similar so this doesn't look confusing
797 * in ps or htop output. */
798 memset(optarg, 'x', strlen(optarg));
799
800 arg_action = ACTION_VERIFY;
801 arg_merge = false;
802 break;
803
804 case ARG_INTERVAL:
805 r = parse_sec(optarg, &arg_interval);
806 if (r < 0 || arg_interval <= 0)
807 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
808 "Failed to parse sealing key change interval: %s", optarg);
809 break;
810 #else
811 case ARG_SETUP_KEYS:
812 case ARG_VERIFY_KEY:
813 case ARG_INTERVAL:
814 case ARG_FORCE:
815 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
816 "Compiled without forward-secure sealing support.");
817 #endif
818
819 case 'p': {
820 const char *dots;
821
822 dots = strstr(optarg, "..");
823 if (dots) {
824 _cleanup_free_ char *a = NULL;
825 int from, to, i;
826
827 /* a range */
828 a = strndup(optarg, dots - optarg);
829 if (!a)
830 return log_oom();
831
832 from = log_level_from_string(a);
833 to = log_level_from_string(dots + 2);
834
835 if (from < 0 || to < 0)
836 return log_error_errno(from < 0 ? from : to,
837 "Failed to parse log level range %s", optarg);
838
839 arg_priorities = 0;
840
841 if (from < to) {
842 for (i = from; i <= to; i++)
843 arg_priorities |= 1 << i;
844 } else {
845 for (i = to; i <= from; i++)
846 arg_priorities |= 1 << i;
847 }
848
849 } else {
850 int p, i;
851
852 p = log_level_from_string(optarg);
853 if (p < 0)
854 return log_error_errno(p, "Unknown log level %s", optarg);
855
856 arg_priorities = 0;
857
858 for (i = 0; i <= p; i++)
859 arg_priorities |= 1 << i;
860 }
861
862 break;
863 }
864
865 case ARG_FACILITY: {
866 const char *p;
867
868 for (p = optarg;;) {
869 _cleanup_free_ char *fac = NULL;
870 int num;
871
872 r = extract_first_word(&p, &fac, ",", 0);
873 if (r < 0)
874 return log_error_errno(r, "Failed to parse facilities: %s", optarg);
875 if (r == 0)
876 break;
877
878 if (streq(fac, "help")) {
879 help_facilities();
880 return 0;
881 }
882
883 num = log_facility_unshifted_from_string(fac);
884 if (num < 0)
885 return log_error_errno(num, "Bad --facility= argument \"%s\".", fac);
886
887 if (set_ensure_put(&arg_facilities, NULL, INT_TO_PTR(num)) < 0)
888 return log_oom();
889 }
890
891 break;
892 }
893
894 case 'g':
895 arg_pattern = optarg;
896 break;
897
898 case ARG_CASE_SENSITIVE:
899 if (optarg) {
900 r = parse_boolean(optarg);
901 if (r < 0)
902 return log_error_errno(r, "Bad --case-sensitive= argument \"%s\": %m", optarg);
903 arg_case = r ? PATTERN_COMPILE_CASE_SENSITIVE : PATTERN_COMPILE_CASE_INSENSITIVE;
904 } else
905 arg_case = PATTERN_COMPILE_CASE_SENSITIVE;
906
907 break;
908
909 case 'S':
910 r = parse_timestamp(optarg, &arg_since);
911 if (r < 0)
912 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
913 "Failed to parse timestamp: %s", optarg);
914 arg_since_set = true;
915 break;
916
917 case 'U':
918 r = parse_timestamp(optarg, &arg_until);
919 if (r < 0)
920 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
921 "Failed to parse timestamp: %s", optarg);
922 arg_until_set = true;
923 break;
924
925 case 't':
926 r = strv_extend(&arg_syslog_identifier, optarg);
927 if (r < 0)
928 return log_oom();
929 break;
930
931 case 'u':
932 r = strv_extend(&arg_system_units, optarg);
933 if (r < 0)
934 return log_oom();
935 break;
936
937 case ARG_USER_UNIT:
938 r = strv_extend(&arg_user_units, optarg);
939 if (r < 0)
940 return log_oom();
941 break;
942
943 case 'F':
944 arg_action = ACTION_LIST_FIELDS;
945 arg_field = optarg;
946 break;
947
948 case 'N':
949 arg_action = ACTION_LIST_FIELD_NAMES;
950 break;
951
952 case ARG_NO_HOSTNAME:
953 arg_no_hostname = true;
954 break;
955
956 case 'x':
957 arg_catalog = true;
958 break;
959
960 case ARG_LIST_CATALOG:
961 arg_action = ACTION_LIST_CATALOG;
962 break;
963
964 case ARG_DUMP_CATALOG:
965 arg_action = ACTION_DUMP_CATALOG;
966 break;
967
968 case ARG_UPDATE_CATALOG:
969 arg_action = ACTION_UPDATE_CATALOG;
970 break;
971
972 case 'r':
973 arg_reverse = true;
974 break;
975
976 case ARG_UTC:
977 arg_utc = true;
978 break;
979
980 case ARG_FLUSH:
981 arg_action = ACTION_FLUSH;
982 break;
983
984 case ARG_SMART_RELINQUISH_VAR: {
985 int root_mnt_id, log_mnt_id;
986
987 /* Try to be smart about relinquishing access to /var/log/journal/ during shutdown:
988 * if it's on the same mount as the root file system there's no point in
989 * relinquishing access and we can leave journald write to it until the very last
990 * moment. */
991
992 r = path_get_mnt_id("/", &root_mnt_id);
993 if (r < 0)
994 log_debug_errno(r, "Failed to get root mount ID, ignoring: %m");
995 else {
996 r = path_get_mnt_id("/var/log/journal/", &log_mnt_id);
997 if (r < 0)
998 log_debug_errno(r, "Failed to get journal directory mount ID, ignoring: %m");
999 else if (root_mnt_id == log_mnt_id) {
1000 log_debug("/var/log/journal/ is on root file system, not relinquishing access to /var.");
1001 return 0;
1002 } else
1003 log_debug("/var/log/journal/ is not on the root file system, relinquishing access to it.");
1004 }
1005
1006 _fallthrough_;
1007 }
1008
1009 case ARG_RELINQUISH_VAR:
1010 arg_action = ACTION_RELINQUISH_VAR;
1011 break;
1012
1013 case ARG_ROTATE:
1014 arg_action = arg_action == ACTION_VACUUM ? ACTION_ROTATE_AND_VACUUM : ACTION_ROTATE;
1015 break;
1016
1017 case ARG_SYNC:
1018 arg_action = ACTION_SYNC;
1019 break;
1020
1021 case ARG_OUTPUT_FIELDS: {
1022 _cleanup_strv_free_ char **v = NULL;
1023
1024 v = strv_split(optarg, ",");
1025 if (!v)
1026 return log_oom();
1027
1028 if (!arg_output_fields)
1029 arg_output_fields = TAKE_PTR(v);
1030 else {
1031 r = strv_extend_strv(&arg_output_fields, v, true);
1032 if (r < 0)
1033 return log_oom();
1034 }
1035 break;
1036 }
1037
1038 case '?':
1039 return -EINVAL;
1040
1041 default:
1042 assert_not_reached();
1043 }
1044
1045 if (arg_follow && !arg_no_tail && !arg_since && arg_lines == ARG_LINES_DEFAULT)
1046 arg_lines = 10;
1047
1048 if (!!arg_directory + !!arg_file + !!arg_machine + !!arg_root + !!arg_image > 1)
1049 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
1050 "Please specify at most one of -D/--directory=, --file=, -M/--machine=, --root=, --image=.");
1051
1052 if (arg_since_set && arg_until_set && arg_since > arg_until)
1053 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
1054 "--since= must be before --until=.");
1055
1056 if (!!arg_cursor + !!arg_after_cursor + !!arg_since_set > 1)
1057 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
1058 "Please specify only one of --since=, --cursor=, and --after-cursor=.");
1059
1060 if (arg_follow && arg_reverse)
1061 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
1062 "Please specify either --reverse= or --follow=, not both.");
1063
1064 if (!IN_SET(arg_action, ACTION_SHOW, ACTION_DUMP_CATALOG, ACTION_LIST_CATALOG) && optind < argc)
1065 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
1066 "Extraneous arguments starting with '%s'",
1067 argv[optind]);
1068
1069 if ((arg_boot || arg_action == ACTION_LIST_BOOTS) && arg_merge)
1070 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
1071 "Using --boot or --list-boots with --merge is not supported.");
1072
1073 if (!strv_isempty(arg_system_units) && arg_journal_type == SD_JOURNAL_CURRENT_USER) {
1074 /* Specifying --user and --unit= at the same time makes no sense (as the former excludes the user
1075 * journal, but the latter excludes the system journal, thus resulting in empty output). Let's be nice
1076 * to users, and automatically turn --unit= into --user-unit= if combined with --user. */
1077 r = strv_extend_strv(&arg_user_units, arg_system_units, true);
1078 if (r < 0)
1079 return r;
1080
1081 arg_system_units = strv_free(arg_system_units);
1082 }
1083
1084 if (arg_pattern) {
1085 r = pattern_compile_and_log(arg_pattern, arg_case, &arg_compiled_pattern);
1086 if (r < 0)
1087 return r;
1088 }
1089
1090 return 1;
1091 }
1092
1093 static int add_matches(sd_journal *j, char **args) {
1094 bool have_term = false;
1095
1096 assert(j);
1097
1098 STRV_FOREACH(i, args) {
1099 int r;
1100
1101 if (streq(*i, "+")) {
1102 if (!have_term)
1103 break;
1104 r = sd_journal_add_disjunction(j);
1105 have_term = false;
1106
1107 } else if (path_is_absolute(*i)) {
1108 _cleanup_free_ char *p = NULL, *t = NULL, *t2 = NULL, *interpreter = NULL;
1109 struct stat st;
1110
1111 r = chase_symlinks(*i, NULL, CHASE_TRAIL_SLASH, &p, NULL);
1112 if (r < 0)
1113 return log_error_errno(r, "Couldn't canonicalize path: %m");
1114
1115 if (lstat(p, &st) < 0)
1116 return log_error_errno(errno, "Couldn't stat file: %m");
1117
1118 if (S_ISREG(st.st_mode) && (0111 & st.st_mode)) {
1119 if (executable_is_script(p, &interpreter) > 0) {
1120 _cleanup_free_ char *comm = NULL;
1121
1122 comm = strndup(basename(p), 15);
1123 if (!comm)
1124 return log_oom();
1125
1126 t = strjoin("_COMM=", comm);
1127 if (!t)
1128 return log_oom();
1129
1130 /* Append _EXE only if the interpreter is not a link.
1131 Otherwise, it might be outdated often. */
1132 if (lstat(interpreter, &st) == 0 && !S_ISLNK(st.st_mode)) {
1133 t2 = strjoin("_EXE=", interpreter);
1134 if (!t2)
1135 return log_oom();
1136 }
1137 } else {
1138 t = strjoin("_EXE=", p);
1139 if (!t)
1140 return log_oom();
1141 }
1142
1143 r = sd_journal_add_match(j, t, 0);
1144
1145 if (r >=0 && t2)
1146 r = sd_journal_add_match(j, t2, 0);
1147
1148 } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
1149 r = add_matches_for_device(j, p);
1150 if (r < 0)
1151 return r;
1152 } else
1153 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
1154 "File is neither a device node, nor regular file, nor executable: %s",
1155 *i);
1156
1157 have_term = true;
1158 } else {
1159 r = sd_journal_add_match(j, *i, 0);
1160 have_term = true;
1161 }
1162
1163 if (r < 0)
1164 return log_error_errno(r, "Failed to add match '%s': %m", *i);
1165 }
1166
1167 if (!strv_isempty(args) && !have_term)
1168 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
1169 "\"+\" can only be used between terms");
1170
1171 return 0;
1172 }
1173
1174 static void boot_id_free_all(BootId *l) {
1175
1176 while (l) {
1177 BootId *i = l;
1178 LIST_REMOVE(boot_list, l, i);
1179 free(i);
1180 }
1181 }
1182
1183 static int discover_next_boot(sd_journal *j,
1184 sd_id128_t previous_boot_id,
1185 bool advance_older,
1186 BootId **ret) {
1187
1188 _cleanup_free_ BootId *next_boot = NULL;
1189 char match[STRLEN("_BOOT_ID=") + SD_ID128_STRING_MAX] = "_BOOT_ID=";
1190 sd_id128_t boot_id;
1191 int r;
1192
1193 assert(j);
1194 assert(ret);
1195
1196 /* We expect the journal to be on the last position of a boot
1197 * (in relation to the direction we are going), so that the next
1198 * invocation of sd_journal_next/previous will be from a different
1199 * boot. We then collect any information we desire and then jump
1200 * to the last location of the new boot by using a _BOOT_ID match
1201 * coming from the other journal direction. */
1202
1203 /* Make sure we aren't restricted by any _BOOT_ID matches, so that
1204 * we can actually advance to a *different* boot. */
1205 sd_journal_flush_matches(j);
1206
1207 do {
1208 if (advance_older)
1209 r = sd_journal_previous(j);
1210 else
1211 r = sd_journal_next(j);
1212 if (r < 0)
1213 return r;
1214 else if (r == 0)
1215 return 0; /* End of journal, yay. */
1216
1217 r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
1218 if (r < 0)
1219 return r;
1220
1221 /* We iterate through this in a loop, until the boot ID differs from the previous one. Note that
1222 * normally, this will only require a single iteration, as we seeked to the last entry of the previous
1223 * boot entry already. However, it might happen that the per-journal-field entry arrays are less
1224 * complete than the main entry array, and hence might reference an entry that's not actually the last
1225 * one of the boot ID as last one. Let's hence use the per-field array is initial seek position to
1226 * speed things up, but let's not trust that it is complete, and hence, manually advance as
1227 * necessary. */
1228
1229 } while (sd_id128_equal(boot_id, previous_boot_id));
1230
1231 next_boot = new0(BootId, 1);
1232 if (!next_boot)
1233 return -ENOMEM;
1234
1235 next_boot->id = boot_id;
1236
1237 r = sd_journal_get_realtime_usec(j, &next_boot->first);
1238 if (r < 0)
1239 return r;
1240
1241 /* Now seek to the last occurrence of this boot ID. */
1242 sd_id128_to_string(next_boot->id, match + STRLEN("_BOOT_ID="));
1243 r = sd_journal_add_match(j, match, sizeof(match) - 1);
1244 if (r < 0)
1245 return r;
1246
1247 if (advance_older)
1248 r = sd_journal_seek_head(j);
1249 else
1250 r = sd_journal_seek_tail(j);
1251 if (r < 0)
1252 return r;
1253
1254 if (advance_older)
1255 r = sd_journal_next(j);
1256 else
1257 r = sd_journal_previous(j);
1258 if (r < 0)
1259 return r;
1260 else if (r == 0)
1261 return log_debug_errno(SYNTHETIC_ERRNO(ENODATA),
1262 "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. */
1263
1264 r = sd_journal_get_realtime_usec(j, &next_boot->last);
1265 if (r < 0)
1266 return r;
1267
1268 *ret = TAKE_PTR(next_boot);
1269
1270 return 0;
1271 }
1272
1273 static int get_boots(
1274 sd_journal *j,
1275 BootId **boots,
1276 sd_id128_t *boot_id,
1277 int offset) {
1278
1279 bool skip_once;
1280 int r, count = 0;
1281 BootId *head = NULL, *tail = NULL;
1282 const bool advance_older = boot_id && offset <= 0;
1283 sd_id128_t previous_boot_id;
1284
1285 assert(j);
1286
1287 /* Adjust for the asymmetry that offset 0 is
1288 * the last (and current) boot, while 1 is considered the
1289 * (chronological) first boot in the journal. */
1290 skip_once = boot_id && sd_id128_is_null(*boot_id) && offset <= 0;
1291
1292 /* Advance to the earliest/latest occurrence of our reference
1293 * boot ID (taking our lookup direction into account), so that
1294 * discover_next_boot() can do its job.
1295 * If no reference is given, the journal head/tail will do,
1296 * they're "virtual" boots after all. */
1297 if (boot_id && !sd_id128_is_null(*boot_id)) {
1298 char match[STRLEN("_BOOT_ID=") + SD_ID128_STRING_MAX] = "_BOOT_ID=";
1299
1300 sd_journal_flush_matches(j);
1301
1302 sd_id128_to_string(*boot_id, match + STRLEN("_BOOT_ID="));
1303 r = sd_journal_add_match(j, match, sizeof(match) - 1);
1304 if (r < 0)
1305 return r;
1306
1307 if (advance_older)
1308 r = sd_journal_seek_head(j); /* seek to oldest */
1309 else
1310 r = sd_journal_seek_tail(j); /* seek to newest */
1311 if (r < 0)
1312 return r;
1313
1314 if (advance_older)
1315 r = sd_journal_next(j); /* read the oldest entry */
1316 else
1317 r = sd_journal_previous(j); /* read the most recently added entry */
1318 if (r < 0)
1319 return r;
1320 else if (r == 0)
1321 goto finish;
1322 else if (offset == 0) {
1323 count = 1;
1324 goto finish;
1325 }
1326
1327 /* At this point the read pointer is positioned at the oldest/newest occurrence of the reference boot
1328 * ID. After flushing the matches, one more invocation of _previous()/_next() will hence place us at
1329 * the following entry, which must then have an older/newer boot ID */
1330 } else {
1331
1332 if (advance_older)
1333 r = sd_journal_seek_tail(j); /* seek to newest */
1334 else
1335 r = sd_journal_seek_head(j); /* seek to oldest */
1336 if (r < 0)
1337 return r;
1338
1339 /* No sd_journal_next()/_previous() here.
1340 *
1341 * At this point the read pointer is positioned after the newest/before the oldest entry in the whole
1342 * journal. The next invocation of _previous()/_next() will hence position us at the newest/oldest
1343 * entry we have. */
1344 }
1345
1346 previous_boot_id = SD_ID128_NULL;
1347 for (;;) {
1348 _cleanup_free_ BootId *current = NULL;
1349
1350 r = discover_next_boot(j, previous_boot_id, advance_older, &current);
1351 if (r < 0) {
1352 boot_id_free_all(head);
1353 return r;
1354 }
1355
1356 if (!current)
1357 break;
1358
1359 previous_boot_id = current->id;
1360
1361 if (boot_id) {
1362 if (!skip_once)
1363 offset += advance_older ? 1 : -1;
1364 skip_once = false;
1365
1366 if (offset == 0) {
1367 count = 1;
1368 *boot_id = current->id;
1369 break;
1370 }
1371 } else {
1372 LIST_FOREACH(boot_list, id, head) {
1373 if (sd_id128_equal(id->id, current->id)) {
1374 /* boot id already stored, something wrong with the journal files */
1375 /* exiting as otherwise this problem would cause forever loop */
1376 goto finish;
1377 }
1378 }
1379 LIST_INSERT_AFTER(boot_list, head, tail, current);
1380 tail = TAKE_PTR(current);
1381 count++;
1382 }
1383 }
1384
1385 finish:
1386 if (boots)
1387 *boots = head;
1388
1389 sd_journal_flush_matches(j);
1390
1391 return count;
1392 }
1393
1394 static int list_boots(sd_journal *j) {
1395 _cleanup_(table_unrefp) Table *table = NULL;
1396 BootId *all_ids;
1397 int count, i, r;
1398
1399 assert(j);
1400
1401 count = get_boots(j, &all_ids, NULL, 0);
1402 if (count < 0)
1403 return log_error_errno(count, "Failed to determine boots: %m");
1404 if (count == 0)
1405 return count;
1406
1407 table = table_new("idx", "boot id", "first entry", "last entry");
1408 if (!table)
1409 return log_oom();
1410
1411 if (arg_full)
1412 table_set_width(table, 0);
1413
1414 r = table_set_json_field_name(table, 0, "index");
1415 if (r < 0)
1416 return log_error_errno(r, "Failed to set JSON field name of column 0: %m");
1417
1418 (void) table_set_sort(table, (size_t) 0);
1419 (void) table_set_reverse(table, 0, arg_reverse);
1420
1421 i = 0;
1422 LIST_FOREACH(boot_list, id, all_ids) {
1423 r = table_add_many(table,
1424 TABLE_INT, i - count + 1,
1425 TABLE_SET_ALIGN_PERCENT, 100,
1426 TABLE_ID128, id->id,
1427 TABLE_TIMESTAMP, id->first,
1428 TABLE_TIMESTAMP, id->last);
1429 if (r < 0)
1430 return table_log_add_error(r);
1431 i++;
1432 }
1433
1434 r = table_print_with_pager(table, arg_json_format_flags, arg_pager_flags, !arg_quiet);
1435 if (r < 0)
1436 return table_log_print_error(r);
1437
1438 boot_id_free_all(all_ids);
1439
1440 return 0;
1441 }
1442
1443 static int add_boot(sd_journal *j) {
1444 char match[STRLEN("_BOOT_ID=") + SD_ID128_STRING_MAX] = "_BOOT_ID=";
1445 sd_id128_t boot_id;
1446 int r;
1447
1448 assert(j);
1449
1450 if (!arg_boot)
1451 return 0;
1452
1453 /* Take a shortcut and use the current boot_id, which we can do very quickly.
1454 * We can do this only when we logs are coming from the current machine,
1455 * so take the slow path if log location is specified. */
1456 if (arg_boot_offset == 0 && sd_id128_is_null(arg_boot_id) &&
1457 !arg_directory && !arg_file && !arg_root)
1458 return add_match_this_boot(j, arg_machine);
1459
1460 boot_id = arg_boot_id;
1461 r = get_boots(j, NULL, &boot_id, arg_boot_offset);
1462 assert(r <= 1);
1463 if (r <= 0) {
1464 const char *reason = (r == 0) ? "No such boot ID in journal" : STRERROR(r);
1465
1466 if (sd_id128_is_null(arg_boot_id))
1467 log_error("Data from the specified boot (%+i) is not available: %s",
1468 arg_boot_offset, reason);
1469 else
1470 log_error("Data from the specified boot ("SD_ID128_FORMAT_STR") is not available: %s",
1471 SD_ID128_FORMAT_VAL(arg_boot_id), reason);
1472
1473 return r == 0 ? -ENODATA : r;
1474 }
1475
1476 sd_id128_to_string(boot_id, match + STRLEN("_BOOT_ID="));
1477
1478 r = sd_journal_add_match(j, match, sizeof(match) - 1);
1479 if (r < 0)
1480 return log_error_errno(r, "Failed to add match: %m");
1481
1482 r = sd_journal_add_conjunction(j);
1483 if (r < 0)
1484 return log_error_errno(r, "Failed to add conjunction: %m");
1485
1486 return 0;
1487 }
1488
1489 static int add_dmesg(sd_journal *j) {
1490 int r;
1491 assert(j);
1492
1493 if (!arg_dmesg)
1494 return 0;
1495
1496 r = sd_journal_add_match(j, "_TRANSPORT=kernel",
1497 STRLEN("_TRANSPORT=kernel"));
1498 if (r < 0)
1499 return log_error_errno(r, "Failed to add match: %m");
1500
1501 r = sd_journal_add_conjunction(j);
1502 if (r < 0)
1503 return log_error_errno(r, "Failed to add conjunction: %m");
1504
1505 return 0;
1506 }
1507
1508 static int get_possible_units(
1509 sd_journal *j,
1510 const char *fields,
1511 char **patterns,
1512 Set **units) {
1513
1514 _cleanup_set_free_free_ Set *found = NULL;
1515 int r;
1516
1517 found = set_new(&string_hash_ops);
1518 if (!found)
1519 return -ENOMEM;
1520
1521 NULSTR_FOREACH(field, fields) {
1522 const void *data;
1523 size_t size;
1524
1525 r = sd_journal_query_unique(j, field);
1526 if (r < 0)
1527 return r;
1528
1529 SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
1530 char *eq;
1531 size_t prefix;
1532 _cleanup_free_ char *u = NULL;
1533
1534 eq = memchr(data, '=', size);
1535 if (eq)
1536 prefix = eq - (char*) data + 1;
1537 else
1538 prefix = 0;
1539
1540 u = strndup((char*) data + prefix, size - prefix);
1541 if (!u)
1542 return -ENOMEM;
1543
1544 STRV_FOREACH(pattern, patterns)
1545 if (fnmatch(*pattern, u, FNM_NOESCAPE) == 0) {
1546 log_debug("Matched %s with pattern %s=%s", u, field, *pattern);
1547
1548 r = set_consume(found, u);
1549 u = NULL;
1550 if (r < 0 && r != -EEXIST)
1551 return r;
1552
1553 break;
1554 }
1555 }
1556 }
1557
1558 *units = TAKE_PTR(found);
1559
1560 return 0;
1561 }
1562
1563 /* This list is supposed to return the superset of unit names
1564 * possibly matched by rules added with add_matches_for_unit... */
1565 #define SYSTEM_UNITS \
1566 "_SYSTEMD_UNIT\0" \
1567 "COREDUMP_UNIT\0" \
1568 "UNIT\0" \
1569 "OBJECT_SYSTEMD_UNIT\0" \
1570 "_SYSTEMD_SLICE\0"
1571
1572 /* ... and add_matches_for_user_unit */
1573 #define USER_UNITS \
1574 "_SYSTEMD_USER_UNIT\0" \
1575 "USER_UNIT\0" \
1576 "COREDUMP_USER_UNIT\0" \
1577 "OBJECT_SYSTEMD_USER_UNIT\0" \
1578 "_SYSTEMD_USER_SLICE\0"
1579
1580 static int add_units(sd_journal *j) {
1581 _cleanup_strv_free_ char **patterns = NULL;
1582 int r, count = 0;
1583
1584 assert(j);
1585
1586 STRV_FOREACH(i, arg_system_units) {
1587 _cleanup_free_ char *u = NULL;
1588
1589 r = unit_name_mangle(*i, UNIT_NAME_MANGLE_GLOB | (arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN), &u);
1590 if (r < 0)
1591 return r;
1592
1593 if (string_is_glob(u)) {
1594 r = strv_push(&patterns, u);
1595 if (r < 0)
1596 return r;
1597 u = NULL;
1598 } else {
1599 r = add_matches_for_unit(j, u);
1600 if (r < 0)
1601 return r;
1602 r = sd_journal_add_disjunction(j);
1603 if (r < 0)
1604 return r;
1605 count++;
1606 }
1607 }
1608
1609 if (!strv_isempty(patterns)) {
1610 _cleanup_set_free_free_ Set *units = NULL;
1611 char *u;
1612
1613 r = get_possible_units(j, SYSTEM_UNITS, patterns, &units);
1614 if (r < 0)
1615 return r;
1616
1617 SET_FOREACH(u, units) {
1618 r = add_matches_for_unit(j, u);
1619 if (r < 0)
1620 return r;
1621 r = sd_journal_add_disjunction(j);
1622 if (r < 0)
1623 return r;
1624 count++;
1625 }
1626 }
1627
1628 patterns = strv_free(patterns);
1629
1630 STRV_FOREACH(i, arg_user_units) {
1631 _cleanup_free_ char *u = NULL;
1632
1633 r = unit_name_mangle(*i, UNIT_NAME_MANGLE_GLOB | (arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN), &u);
1634 if (r < 0)
1635 return r;
1636
1637 if (string_is_glob(u)) {
1638 r = strv_push(&patterns, u);
1639 if (r < 0)
1640 return r;
1641 u = NULL;
1642 } else {
1643 r = add_matches_for_user_unit(j, u, getuid());
1644 if (r < 0)
1645 return r;
1646 r = sd_journal_add_disjunction(j);
1647 if (r < 0)
1648 return r;
1649 count++;
1650 }
1651 }
1652
1653 if (!strv_isempty(patterns)) {
1654 _cleanup_set_free_free_ Set *units = NULL;
1655 char *u;
1656
1657 r = get_possible_units(j, USER_UNITS, patterns, &units);
1658 if (r < 0)
1659 return r;
1660
1661 SET_FOREACH(u, units) {
1662 r = add_matches_for_user_unit(j, u, getuid());
1663 if (r < 0)
1664 return r;
1665 r = sd_journal_add_disjunction(j);
1666 if (r < 0)
1667 return r;
1668 count++;
1669 }
1670 }
1671
1672 /* Complain if the user request matches but nothing whatsoever was
1673 * found, since otherwise everything would be matched. */
1674 if (!(strv_isempty(arg_system_units) && strv_isempty(arg_user_units)) && count == 0)
1675 return -ENODATA;
1676
1677 r = sd_journal_add_conjunction(j);
1678 if (r < 0)
1679 return r;
1680
1681 return 0;
1682 }
1683
1684 static int add_priorities(sd_journal *j) {
1685 char match[] = "PRIORITY=0";
1686 int i, r;
1687 assert(j);
1688
1689 if (arg_priorities == 0xFF)
1690 return 0;
1691
1692 for (i = LOG_EMERG; i <= LOG_DEBUG; i++)
1693 if (arg_priorities & (1 << i)) {
1694 match[sizeof(match)-2] = '0' + i;
1695
1696 r = sd_journal_add_match(j, match, strlen(match));
1697 if (r < 0)
1698 return log_error_errno(r, "Failed to add match: %m");
1699 }
1700
1701 r = sd_journal_add_conjunction(j);
1702 if (r < 0)
1703 return log_error_errno(r, "Failed to add conjunction: %m");
1704
1705 return 0;
1706 }
1707
1708 static int add_facilities(sd_journal *j) {
1709 void *p;
1710 int r;
1711
1712 SET_FOREACH(p, arg_facilities) {
1713 char match[STRLEN("SYSLOG_FACILITY=") + DECIMAL_STR_MAX(int)];
1714
1715 xsprintf(match, "SYSLOG_FACILITY=%d", PTR_TO_INT(p));
1716
1717 r = sd_journal_add_match(j, match, strlen(match));
1718 if (r < 0)
1719 return log_error_errno(r, "Failed to add match: %m");
1720 }
1721
1722 return 0;
1723 }
1724
1725 static int add_syslog_identifier(sd_journal *j) {
1726 int r;
1727
1728 assert(j);
1729
1730 STRV_FOREACH(i, arg_syslog_identifier) {
1731 _cleanup_free_ char *u = NULL;
1732
1733 u = strjoin("SYSLOG_IDENTIFIER=", *i);
1734 if (!u)
1735 return -ENOMEM;
1736 r = sd_journal_add_match(j, u, 0);
1737 if (r < 0)
1738 return r;
1739 r = sd_journal_add_disjunction(j);
1740 if (r < 0)
1741 return r;
1742 }
1743
1744 r = sd_journal_add_conjunction(j);
1745 if (r < 0)
1746 return r;
1747
1748 return 0;
1749 }
1750
1751 #if HAVE_GCRYPT
1752 static int format_journal_url(
1753 const void *seed,
1754 size_t seed_size,
1755 uint64_t start,
1756 uint64_t interval,
1757 const char *hn,
1758 sd_id128_t machine,
1759 bool full,
1760 char **ret_url) {
1761 _cleanup_free_ char *url = NULL;
1762 _cleanup_fclose_ FILE *f = NULL;
1763 size_t url_size = 0;
1764 int r;
1765
1766 assert(seed);
1767 assert(seed_size > 0);
1768
1769 f = open_memstream_unlocked(&url, &url_size);
1770 if (!f)
1771 return -ENOMEM;
1772
1773 if (full)
1774 fputs("fss://", f);
1775
1776 for (size_t i = 0; i < seed_size; i++) {
1777 if (i > 0 && i % 3 == 0)
1778 fputc('-', f);
1779 fprintf(f, "%02x", ((uint8_t*) seed)[i]);
1780 }
1781
1782 fprintf(f, "/%"PRIx64"-%"PRIx64, start, interval);
1783
1784 if (full) {
1785 fprintf(f, "?machine=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(machine));
1786 if (hn)
1787 fprintf(f, ";hostname=%s", hn);
1788 }
1789
1790 r = fflush_and_check(f);
1791 if (r < 0)
1792 return r;
1793
1794 f = safe_fclose(f);
1795 *ret_url = TAKE_PTR(url);
1796 return 0;
1797 }
1798 #endif
1799
1800 static int setup_keys(void) {
1801 #if HAVE_GCRYPT
1802 size_t mpk_size, seed_size, state_size;
1803 _cleanup_(unlink_and_freep) char *k = NULL;
1804 _cleanup_free_ char *p = NULL;
1805 uint8_t *mpk, *seed, *state;
1806 _cleanup_close_ int fd = -EBADF;
1807 sd_id128_t machine, boot;
1808 struct stat st;
1809 uint64_t n;
1810 int r;
1811
1812 r = stat("/var/log/journal", &st);
1813 if (r < 0 && !IN_SET(errno, ENOENT, ENOTDIR))
1814 return log_error_errno(errno, "stat(\"%s\") failed: %m", "/var/log/journal");
1815
1816 if (r < 0 || !S_ISDIR(st.st_mode)) {
1817 log_error("%s is not a directory, must be using persistent logging for FSS.",
1818 "/var/log/journal");
1819 return r < 0 ? -errno : -ENOTDIR;
1820 }
1821
1822 r = sd_id128_get_machine(&machine);
1823 if (r < 0)
1824 return log_error_errno(r, "Failed to get machine ID: %m");
1825
1826 r = sd_id128_get_boot(&boot);
1827 if (r < 0)
1828 return log_error_errno(r, "Failed to get boot ID: %m");
1829
1830 if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss",
1831 SD_ID128_FORMAT_VAL(machine)) < 0)
1832 return log_oom();
1833
1834 if (arg_force) {
1835 r = unlink(p);
1836 if (r < 0 && errno != ENOENT)
1837 return log_error_errno(errno, "unlink(\"%s\") failed: %m", p);
1838 } else if (access(p, F_OK) >= 0)
1839 return log_error_errno(SYNTHETIC_ERRNO(EEXIST),
1840 "Sealing key file %s exists already. Use --force to recreate.", p);
1841
1842 if (asprintf(&k, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss.tmp.XXXXXX",
1843 SD_ID128_FORMAT_VAL(machine)) < 0)
1844 return log_oom();
1845
1846 mpk_size = FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR);
1847 mpk = alloca_safe(mpk_size);
1848
1849 seed_size = FSPRG_RECOMMENDED_SEEDLEN;
1850 seed = alloca_safe(seed_size);
1851
1852 state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
1853 state = alloca_safe(state_size);
1854
1855 log_info("Generating seed...");
1856 r = crypto_random_bytes(seed, seed_size);
1857 if (r < 0)
1858 return log_error_errno(r, "Failed to acquire random seed: %m");
1859
1860 log_info("Generating key pair...");
1861 FSPRG_GenMK(NULL, mpk, seed, seed_size, FSPRG_RECOMMENDED_SECPAR);
1862
1863 log_info("Generating sealing key...");
1864 FSPRG_GenState0(state, mpk, seed, seed_size);
1865
1866 assert(arg_interval > 0);
1867
1868 n = now(CLOCK_REALTIME);
1869 n /= arg_interval;
1870
1871 safe_close(fd);
1872 fd = mkostemp_safe(k);
1873 if (fd < 0)
1874 return log_error_errno(fd, "Failed to open %s: %m", k);
1875
1876 r = chattr_secret(fd, CHATTR_WARN_UNSUPPORTED_FLAGS);
1877 if (r < 0)
1878 log_full_errno(ERRNO_IS_NOT_SUPPORTED(r) ? LOG_DEBUG : LOG_WARNING,
1879 r, "Failed to set file attributes on '%s', ignoring: %m", k);
1880
1881 struct FSSHeader h = {
1882 .signature = { 'K', 'S', 'H', 'H', 'R', 'H', 'L', 'P' },
1883 .machine_id = machine,
1884 .boot_id = boot,
1885 .header_size = htole64(sizeof(h)),
1886 .start_usec = htole64(n * arg_interval),
1887 .interval_usec = htole64(arg_interval),
1888 .fsprg_secpar = htole16(FSPRG_RECOMMENDED_SECPAR),
1889 .fsprg_state_size = htole64(state_size),
1890 };
1891
1892 r = loop_write(fd, &h, sizeof(h), false);
1893 if (r < 0)
1894 return log_error_errno(r, "Failed to write header: %m");
1895
1896 r = loop_write(fd, state, state_size, false);
1897 if (r < 0)
1898 return log_error_errno(r, "Failed to write state: %m");
1899
1900 if (rename(k, p) < 0)
1901 return log_error_errno(errno, "Failed to link file: %m");
1902
1903 k = mfree(k);
1904
1905 _cleanup_free_ char *hn = NULL, *key = NULL;
1906
1907 r = format_journal_url(seed, seed_size, n, arg_interval, hn, machine, false, &key);
1908 if (r < 0)
1909 return r;
1910
1911 if (on_tty()) {
1912 hn = gethostname_malloc();
1913 if (hn)
1914 hostname_cleanup(hn);
1915
1916 fprintf(stderr,
1917 "\nNew keys have been generated for host %s%s" SD_ID128_FORMAT_STR ".\n"
1918 "\n"
1919 "The %ssecret sealing key%s has been written to the following local file.\n"
1920 "This key file is automatically updated when the sealing key is advanced.\n"
1921 "It should not be used on multiple hosts.\n"
1922 "\n"
1923 "\t%s\n"
1924 "\n"
1925 "The sealing key is automatically changed every %s.\n"
1926 "\n"
1927 "Please write down the following %ssecret verification key%s. It should be stored\n"
1928 "in a safe location and should not be saved locally on disk.\n"
1929 "\n\t%s",
1930 strempty(hn), hn ? "/" : "",
1931 SD_ID128_FORMAT_VAL(machine),
1932 ansi_highlight(), ansi_normal(),
1933 p,
1934 FORMAT_TIMESPAN(arg_interval, 0),
1935 ansi_highlight(), ansi_normal(),
1936 ansi_highlight_red());
1937 fflush(stderr);
1938 }
1939
1940 puts(key);
1941
1942 if (on_tty()) {
1943 fprintf(stderr, "%s", ansi_normal());
1944 #if HAVE_QRENCODE
1945 _cleanup_free_ char *url = NULL;
1946 r = format_journal_url(seed, seed_size, n, arg_interval, hn, machine, true, &url);
1947 if (r < 0)
1948 return r;
1949
1950 (void) print_qrcode(stderr,
1951 "To transfer the verification key to your phone scan the QR code below",
1952 url);
1953 #endif
1954 }
1955
1956 return 0;
1957 #else
1958 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
1959 "Forward-secure sealing not available.");
1960 #endif
1961 }
1962
1963 static int verify(sd_journal *j, bool verbose) {
1964 int r = 0;
1965 JournalFile *f;
1966
1967 assert(j);
1968
1969 log_show_color(true);
1970
1971 ORDERED_HASHMAP_FOREACH(f, j->files) {
1972 int k;
1973 usec_t first = 0, validated = 0, last = 0;
1974
1975 #if HAVE_GCRYPT
1976 if (!arg_verify_key && JOURNAL_HEADER_SEALED(f->header))
1977 log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path);
1978 #endif
1979
1980 k = journal_file_verify(f, arg_verify_key, &first, &validated, &last, verbose);
1981 if (k == -EINVAL)
1982 /* If the key was invalid give up right-away. */
1983 return k;
1984 else if (k < 0)
1985 r = log_warning_errno(k, "FAIL: %s (%m)", f->path);
1986 else {
1987 char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX];
1988 log_full(verbose ? LOG_INFO : LOG_DEBUG, "PASS: %s", f->path);
1989
1990 if (arg_verify_key && JOURNAL_HEADER_SEALED(f->header)) {
1991 if (validated > 0) {
1992 log_full(verbose ? LOG_INFO : LOG_DEBUG,
1993 "=> Validated from %s to %s, final %s entries not sealed.",
1994 format_timestamp_maybe_utc(a, sizeof(a), first),
1995 format_timestamp_maybe_utc(b, sizeof(b), validated),
1996 FORMAT_TIMESPAN(last > validated ? last - validated : 0, 0));
1997 } else if (last > 0)
1998 log_full(verbose ? LOG_INFO : LOG_DEBUG,
1999 "=> No sealing yet, %s of entries not sealed.",
2000 FORMAT_TIMESPAN(last - first, 0));
2001 else
2002 log_full(verbose ? LOG_INFO : LOG_DEBUG,
2003 "=> No sealing yet, no entries in file.");
2004 }
2005 }
2006 }
2007
2008 return r;
2009 }
2010
2011 static int simple_varlink_call(const char *option, const char *method) {
2012 _cleanup_(varlink_flush_close_unrefp) Varlink *link = NULL;
2013 const char *error, *fn;
2014 int r;
2015
2016 if (arg_machine)
2017 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "%s is not supported in conjunction with --machine=.", option);
2018
2019 fn = arg_namespace ?
2020 strjoina("/run/systemd/journal.", arg_namespace, "/io.systemd.journal") :
2021 "/run/systemd/journal/io.systemd.journal";
2022
2023 r = varlink_connect_address(&link, fn);
2024 if (r < 0)
2025 return log_error_errno(r, "Failed to connect to %s: %m", fn);
2026
2027 (void) varlink_set_description(link, "journal");
2028 (void) varlink_set_relative_timeout(link, USEC_INFINITY);
2029
2030 r = varlink_call(link, method, NULL, NULL, &error, NULL);
2031 if (r < 0)
2032 return log_error_errno(r, "Failed to execute varlink call: %m");
2033 if (error)
2034 return log_error_errno(SYNTHETIC_ERRNO(ENOANO),
2035 "Failed to execute varlink call: %s", error);
2036
2037 return 0;
2038 }
2039
2040 static int flush_to_var(void) {
2041 if (access("/run/systemd/journal/flushed", F_OK) >= 0)
2042 return 0; /* Already flushed, no need to contact journald */
2043 if (errno != ENOENT)
2044 return log_error_errno(errno, "Unable to check for existence of /run/systemd/journal/flushed: %m");
2045
2046 return simple_varlink_call("--flush", "io.systemd.Journal.FlushToVar");
2047 }
2048
2049 static int relinquish_var(void) {
2050 return simple_varlink_call("--relinquish-var/--smart-relinquish-var", "io.systemd.Journal.RelinquishVar");
2051 }
2052
2053 static int rotate(void) {
2054 return simple_varlink_call("--rotate", "io.systemd.Journal.Rotate");
2055 }
2056
2057 static int sync_journal(void) {
2058 return simple_varlink_call("--sync", "io.systemd.Journal.Synchronize");
2059 }
2060
2061 static int wait_for_change(sd_journal *j, int poll_fd) {
2062 struct pollfd pollfds[] = {
2063 { .fd = poll_fd, .events = POLLIN },
2064 { .fd = STDOUT_FILENO },
2065 };
2066 usec_t timeout;
2067 int r;
2068
2069 assert(j);
2070 assert(poll_fd >= 0);
2071
2072 /* Much like sd_journal_wait() but also keeps an eye on STDOUT, and exits as soon as we see a POLLHUP on that,
2073 * i.e. when it is closed. */
2074
2075 r = sd_journal_get_timeout(j, &timeout);
2076 if (r < 0)
2077 return log_error_errno(r, "Failed to determine journal waiting time: %m");
2078
2079 r = ppoll_usec(pollfds, ELEMENTSOF(pollfds), timeout);
2080 if (r == -EINTR)
2081 return 0;
2082 if (r < 0)
2083 return log_error_errno(r, "Couldn't wait for journal event: %m");
2084
2085 if (pollfds[1].revents & (POLLHUP|POLLERR)) /* STDOUT has been closed? */
2086 return log_debug_errno(SYNTHETIC_ERRNO(ECANCELED),
2087 "Standard output has been closed.");
2088
2089 r = sd_journal_process(j);
2090 if (r < 0)
2091 return log_error_errno(r, "Failed to process journal events: %m");
2092
2093 return 0;
2094 }
2095
2096 int main(int argc, char *argv[]) {
2097 _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
2098 _cleanup_(umount_and_rmdir_and_freep) char *unlink_dir = NULL;
2099 bool previous_boot_id_valid = false, first_line = true, ellipsized = false, need_seek = false;
2100 bool use_cursor = false, after_cursor = false;
2101 _cleanup_(sd_journal_closep) sd_journal *j = NULL;
2102 sd_id128_t previous_boot_id = SD_ID128_NULL, previous_boot_id_output = SD_ID128_NULL;
2103 dual_timestamp previous_ts_output = DUAL_TIMESTAMP_NULL;
2104 int n_shown = 0, r, poll_fd = -EBADF;
2105
2106 setlocale(LC_ALL, "");
2107 log_setup();
2108
2109 /* Increase max number of open files if we can, we might needs this when browsing journal files, which might be
2110 * split up into many files. */
2111 (void) rlimit_nofile_bump(HIGH_RLIMIT_NOFILE);
2112
2113 r = parse_argv(argc, argv);
2114 if (r <= 0)
2115 goto finish;
2116
2117 if (arg_image) {
2118 assert(!arg_root);
2119
2120 r = mount_image_privately_interactively(
2121 arg_image,
2122 DISSECT_IMAGE_GENERIC_ROOT |
2123 DISSECT_IMAGE_REQUIRE_ROOT |
2124 DISSECT_IMAGE_VALIDATE_OS |
2125 DISSECT_IMAGE_RELAX_VAR_CHECK |
2126 (arg_action == ACTION_UPDATE_CATALOG ? DISSECT_IMAGE_FSCK|DISSECT_IMAGE_GROWFS : DISSECT_IMAGE_READ_ONLY),
2127 &unlink_dir,
2128 &loop_device);
2129 if (r < 0)
2130 return r;
2131
2132 arg_root = strdup(unlink_dir);
2133 if (!arg_root)
2134 return log_oom();
2135 }
2136
2137 signal(SIGWINCH, columns_lines_cache_reset);
2138 sigbus_install();
2139
2140 switch (arg_action) {
2141
2142 case ACTION_NEW_ID128:
2143 r = id128_print_new(ID128_PRINT_PRETTY);
2144 goto finish;
2145
2146 case ACTION_SETUP_KEYS:
2147 r = setup_keys();
2148 goto finish;
2149
2150 case ACTION_LIST_CATALOG:
2151 case ACTION_DUMP_CATALOG:
2152 case ACTION_UPDATE_CATALOG: {
2153 _cleanup_free_ char *database = NULL;
2154
2155 database = path_join(arg_root, CATALOG_DATABASE);
2156 if (!database) {
2157 r = log_oom();
2158 goto finish;
2159 }
2160
2161 if (arg_action == ACTION_UPDATE_CATALOG) {
2162 r = catalog_update(database, arg_root, catalog_file_dirs);
2163 if (r < 0)
2164 log_error_errno(r, "Failed to list catalog: %m");
2165 } else {
2166 bool oneline = arg_action == ACTION_LIST_CATALOG;
2167
2168 pager_open(arg_pager_flags);
2169
2170 if (optind < argc)
2171 r = catalog_list_items(stdout, database, oneline, argv + optind);
2172 else
2173 r = catalog_list(stdout, database, oneline);
2174 if (r < 0)
2175 log_error_errno(r, "Failed to list catalog: %m");
2176 }
2177
2178 goto finish;
2179 }
2180
2181 case ACTION_FLUSH:
2182 r = flush_to_var();
2183 goto finish;
2184
2185 case ACTION_RELINQUISH_VAR:
2186 r = relinquish_var();
2187 goto finish;
2188
2189 case ACTION_SYNC:
2190 r = sync_journal();
2191 goto finish;
2192
2193 case ACTION_ROTATE:
2194 r = rotate();
2195 goto finish;
2196
2197 case ACTION_SHOW:
2198 case ACTION_PRINT_HEADER:
2199 case ACTION_VERIFY:
2200 case ACTION_DISK_USAGE:
2201 case ACTION_LIST_BOOTS:
2202 case ACTION_VACUUM:
2203 case ACTION_ROTATE_AND_VACUUM:
2204 case ACTION_LIST_FIELDS:
2205 case ACTION_LIST_FIELD_NAMES:
2206 /* These ones require access to the journal files, continue below. */
2207 break;
2208
2209 default:
2210 assert_not_reached();
2211 }
2212
2213 if (arg_directory)
2214 r = sd_journal_open_directory(&j, arg_directory, arg_journal_type);
2215 else if (arg_root)
2216 r = sd_journal_open_directory(&j, arg_root, arg_journal_type | SD_JOURNAL_OS_ROOT);
2217 else if (arg_file_stdin)
2218 r = sd_journal_open_files_fd(&j, (int[]) { STDIN_FILENO }, 1, 0);
2219 else if (arg_file)
2220 r = sd_journal_open_files(&j, (const char**) arg_file, 0);
2221 else if (arg_machine) {
2222 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2223 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
2224 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
2225 int fd;
2226
2227 if (geteuid() != 0) {
2228 /* The file descriptor returned by OpenMachineRootDirectory() will be owned by users/groups of
2229 * the container, thus we need root privileges to override them. */
2230 r = log_error_errno(SYNTHETIC_ERRNO(EPERM), "Using the --machine= switch requires root privileges.");
2231 goto finish;
2232 }
2233
2234 r = sd_bus_open_system(&bus);
2235 if (r < 0) {
2236 log_error_errno(r, "Failed to open system bus: %m");
2237 goto finish;
2238 }
2239
2240 r = sd_bus_call_method(
2241 bus,
2242 "org.freedesktop.machine1",
2243 "/org/freedesktop/machine1",
2244 "org.freedesktop.machine1.Manager",
2245 "OpenMachineRootDirectory",
2246 &error,
2247 &reply,
2248 "s", arg_machine);
2249 if (r < 0) {
2250 log_error_errno(r, "Failed to open root directory: %s", bus_error_message(&error, r));
2251 goto finish;
2252 }
2253
2254 r = sd_bus_message_read(reply, "h", &fd);
2255 if (r < 0) {
2256 bus_log_parse_error(r);
2257 goto finish;
2258 }
2259
2260 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2261 if (fd < 0) {
2262 r = log_error_errno(errno, "Failed to duplicate file descriptor: %m");
2263 goto finish;
2264 }
2265
2266 r = sd_journal_open_directory_fd(&j, fd, SD_JOURNAL_OS_ROOT);
2267 if (r < 0)
2268 safe_close(fd);
2269 } else
2270 r = sd_journal_open_namespace(
2271 &j,
2272 arg_namespace,
2273 (arg_merge ? 0 : SD_JOURNAL_LOCAL_ONLY) |
2274 arg_namespace_flags | arg_journal_type);
2275 if (r < 0) {
2276 log_error_errno(r, "Failed to open %s: %m", arg_directory ?: arg_file ? "files" : "journal");
2277 goto finish;
2278 }
2279
2280 r = journal_access_check_and_warn(j, arg_quiet,
2281 !(arg_journal_type == SD_JOURNAL_CURRENT_USER || arg_user_units));
2282 if (r < 0)
2283 goto finish;
2284
2285 switch (arg_action) {
2286
2287 case ACTION_NEW_ID128:
2288 case ACTION_SETUP_KEYS:
2289 case ACTION_LIST_CATALOG:
2290 case ACTION_DUMP_CATALOG:
2291 case ACTION_UPDATE_CATALOG:
2292 case ACTION_FLUSH:
2293 case ACTION_SYNC:
2294 case ACTION_ROTATE:
2295 assert_not_reached();
2296
2297 case ACTION_PRINT_HEADER:
2298 journal_print_header(j);
2299 r = 0;
2300 goto finish;
2301
2302 case ACTION_VERIFY:
2303 r = verify(j, !arg_quiet);
2304 goto finish;
2305
2306 case ACTION_DISK_USAGE: {
2307 uint64_t bytes = 0;
2308
2309 r = sd_journal_get_usage(j, &bytes);
2310 if (r < 0)
2311 goto finish;
2312
2313 printf("Archived and active journals take up %s in the file system.\n",
2314 FORMAT_BYTES(bytes));
2315 goto finish;
2316 }
2317
2318 case ACTION_LIST_BOOTS:
2319 r = list_boots(j);
2320 goto finish;
2321
2322 case ACTION_ROTATE_AND_VACUUM:
2323
2324 r = rotate();
2325 if (r < 0)
2326 goto finish;
2327
2328 _fallthrough_;
2329
2330 case ACTION_VACUUM: {
2331 Directory *d;
2332
2333 HASHMAP_FOREACH(d, j->directories_by_path) {
2334 int q;
2335
2336 q = journal_directory_vacuum(d->path, arg_vacuum_size, arg_vacuum_n_files, arg_vacuum_time, NULL, !arg_quiet);
2337 if (q < 0)
2338 r = log_error_errno(q, "Failed to vacuum %s: %m", d->path);
2339 }
2340
2341 goto finish;
2342 }
2343
2344 case ACTION_LIST_FIELD_NAMES: {
2345 const char *field;
2346
2347 SD_JOURNAL_FOREACH_FIELD(j, field) {
2348 printf("%s\n", field);
2349 n_shown++;
2350 }
2351
2352 r = 0;
2353 goto finish;
2354 }
2355
2356 case ACTION_SHOW:
2357 case ACTION_LIST_FIELDS:
2358 break;
2359
2360 default:
2361 assert_not_reached();
2362 }
2363
2364 if (arg_boot_offset != 0 &&
2365 sd_journal_has_runtime_files(j) > 0 &&
2366 sd_journal_has_persistent_files(j) == 0) {
2367 log_info("Specifying boot ID or boot offset has no effect, no persistent journal was found.");
2368 r = 0;
2369 goto finish;
2370 }
2371 /* add_boot() must be called first!
2372 * It may need to seek the journal to find parent boot IDs. */
2373 r = add_boot(j);
2374 if (r < 0)
2375 goto finish;
2376
2377 r = add_dmesg(j);
2378 if (r < 0)
2379 goto finish;
2380
2381 r = add_units(j);
2382 if (r < 0) {
2383 log_error_errno(r, "Failed to add filter for units: %m");
2384 goto finish;
2385 }
2386
2387 r = add_syslog_identifier(j);
2388 if (r < 0) {
2389 log_error_errno(r, "Failed to add filter for syslog identifiers: %m");
2390 goto finish;
2391 }
2392
2393 r = add_priorities(j);
2394 if (r < 0)
2395 goto finish;
2396
2397 r = add_facilities(j);
2398 if (r < 0)
2399 goto finish;
2400
2401 r = add_matches(j, argv + optind);
2402 if (r < 0)
2403 goto finish;
2404
2405 if (DEBUG_LOGGING) {
2406 _cleanup_free_ char *filter = NULL;
2407
2408 filter = journal_make_match_string(j);
2409 if (!filter)
2410 return log_oom();
2411
2412 log_debug("Journal filter: %s", filter);
2413 }
2414
2415 if (arg_action == ACTION_LIST_FIELDS) {
2416 const void *data;
2417 size_t size;
2418
2419 assert(arg_field);
2420
2421 r = sd_journal_set_data_threshold(j, 0);
2422 if (r < 0) {
2423 log_error_errno(r, "Failed to unset data size threshold: %m");
2424 goto finish;
2425 }
2426
2427 r = sd_journal_query_unique(j, arg_field);
2428 if (r < 0) {
2429 log_error_errno(r, "Failed to query unique data objects: %m");
2430 goto finish;
2431 }
2432
2433 SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
2434 const void *eq;
2435
2436 if (arg_lines >= 0 && n_shown >= arg_lines)
2437 break;
2438
2439 eq = memchr(data, '=', size);
2440 if (eq)
2441 printf("%.*s\n", (int) (size - ((const uint8_t*) eq - (const uint8_t*) data + 1)), (const char*) eq + 1);
2442 else
2443 printf("%.*s\n", (int) size, (const char*) data);
2444
2445 n_shown++;
2446 }
2447
2448 r = 0;
2449 goto finish;
2450 }
2451
2452 /* Opening the fd now means the first sd_journal_wait() will actually wait */
2453 if (arg_follow) {
2454 poll_fd = sd_journal_get_fd(j);
2455 if (poll_fd == -EMFILE) {
2456 log_warning_errno(poll_fd, "Insufficient watch descriptors available. Reverting to -n.");
2457 arg_follow = false;
2458 } else if (poll_fd == -EMEDIUMTYPE) {
2459 log_error_errno(poll_fd, "The --follow switch is not supported in conjunction with reading from STDIN.");
2460 goto finish;
2461 } else if (poll_fd < 0) {
2462 log_error_errno(poll_fd, "Failed to get journal fd: %m");
2463 goto finish;
2464 }
2465 }
2466
2467 if (arg_cursor || arg_after_cursor || arg_cursor_file) {
2468 _cleanup_free_ char *cursor_from_file = NULL;
2469 const char *cursor = arg_cursor ?: arg_after_cursor;
2470
2471 if (arg_cursor_file) {
2472 r = read_one_line_file(arg_cursor_file, &cursor_from_file);
2473 if (r < 0 && r != -ENOENT) {
2474 log_error_errno(r, "Failed to read cursor file %s: %m", arg_cursor_file);
2475 goto finish;
2476 }
2477
2478 if (r > 0) {
2479 cursor = cursor_from_file;
2480 after_cursor = true;
2481 }
2482 } else
2483 after_cursor = arg_after_cursor;
2484
2485 if (cursor) {
2486 r = sd_journal_seek_cursor(j, cursor);
2487 if (r < 0) {
2488 log_error_errno(r, "Failed to seek to cursor: %m");
2489 goto finish;
2490 }
2491 use_cursor = true;
2492 }
2493 }
2494
2495 if (use_cursor) {
2496 if (!arg_reverse)
2497 r = sd_journal_next_skip(j, 1 + after_cursor);
2498 else
2499 r = sd_journal_previous_skip(j, 1 + after_cursor);
2500
2501 if (after_cursor && r < 2) {
2502 /* We couldn't find the next entry after the cursor. */
2503 if (arg_follow)
2504 need_seek = true;
2505 else
2506 arg_lines = 0;
2507 }
2508
2509 } else if (arg_since_set && !arg_reverse) {
2510 r = sd_journal_seek_realtime_usec(j, arg_since);
2511 if (r < 0) {
2512 log_error_errno(r, "Failed to seek to date: %m");
2513 goto finish;
2514 }
2515 r = sd_journal_next(j);
2516
2517 } else if (arg_until_set && arg_reverse) {
2518 r = sd_journal_seek_realtime_usec(j, arg_until);
2519 if (r < 0) {
2520 log_error_errno(r, "Failed to seek to date: %m");
2521 goto finish;
2522 }
2523 r = sd_journal_previous(j);
2524
2525 } else if (arg_reverse) {
2526 r = sd_journal_seek_tail(j);
2527 if (r < 0) {
2528 log_error_errno(r, "Failed to seek to tail: %m");
2529 goto finish;
2530 }
2531
2532 r = sd_journal_previous(j);
2533
2534 } else if (arg_lines >= 0) {
2535 r = sd_journal_seek_tail(j);
2536 if (r < 0) {
2537 log_error_errno(r, "Failed to seek to tail: %m");
2538 goto finish;
2539 }
2540
2541 r = sd_journal_previous_skip(j, arg_lines);
2542
2543 } else {
2544 r = sd_journal_seek_head(j);
2545 if (r < 0) {
2546 log_error_errno(r, "Failed to seek to head: %m");
2547 goto finish;
2548 }
2549
2550 r = sd_journal_next(j);
2551 }
2552
2553 if (r < 0) {
2554 log_error_errno(r, "Failed to iterate through journal: %m");
2555 goto finish;
2556 }
2557 if (r == 0)
2558 need_seek = true;
2559
2560 if (!arg_follow)
2561 pager_open(arg_pager_flags);
2562
2563 if (!arg_quiet && (arg_lines != 0 || arg_follow) && DEBUG_LOGGING) {
2564 usec_t start, end;
2565 char start_buf[FORMAT_TIMESTAMP_MAX], end_buf[FORMAT_TIMESTAMP_MAX];
2566
2567 r = sd_journal_get_cutoff_realtime_usec(j, &start, &end);
2568 if (r < 0) {
2569 log_error_errno(r, "Failed to get cutoff: %m");
2570 goto finish;
2571 }
2572
2573 if (r > 0) {
2574 if (arg_follow)
2575 printf("-- Journal begins at %s. --\n",
2576 format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start));
2577 else
2578 printf("-- Journal begins at %s, ends at %s. --\n",
2579 format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start),
2580 format_timestamp_maybe_utc(end_buf, sizeof(end_buf), end));
2581 }
2582 }
2583
2584 for (;;) {
2585 while (arg_lines < 0 || n_shown < arg_lines || (arg_follow && !first_line)) {
2586 int flags;
2587 size_t highlight[2] = {};
2588
2589 if (need_seek) {
2590 if (!arg_reverse)
2591 r = sd_journal_next(j);
2592 else
2593 r = sd_journal_previous(j);
2594 if (r < 0) {
2595 log_error_errno(r, "Failed to iterate through journal: %m");
2596 goto finish;
2597 }
2598 if (r == 0)
2599 break;
2600 }
2601
2602 if (arg_until_set && !arg_reverse) {
2603 usec_t usec;
2604
2605 r = sd_journal_get_realtime_usec(j, &usec);
2606 if (r < 0) {
2607 log_error_errno(r, "Failed to determine timestamp: %m");
2608 goto finish;
2609 }
2610 if (usec > arg_until)
2611 break;
2612 }
2613
2614 if (arg_since_set && arg_reverse) {
2615 usec_t usec;
2616
2617 r = sd_journal_get_realtime_usec(j, &usec);
2618 if (r < 0) {
2619 log_error_errno(r, "Failed to determine timestamp: %m");
2620 goto finish;
2621 }
2622 if (usec < arg_since)
2623 break;
2624 }
2625
2626 if (!arg_merge && !arg_quiet) {
2627 sd_id128_t boot_id;
2628
2629 r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
2630 if (r >= 0) {
2631 if (previous_boot_id_valid &&
2632 !sd_id128_equal(boot_id, previous_boot_id))
2633 printf("%s-- Boot "SD_ID128_FORMAT_STR" --%s\n",
2634 ansi_highlight(), SD_ID128_FORMAT_VAL(boot_id), ansi_normal());
2635
2636 previous_boot_id = boot_id;
2637 previous_boot_id_valid = true;
2638 }
2639 }
2640
2641 if (arg_compiled_pattern) {
2642 const void *message;
2643 size_t len;
2644
2645 r = sd_journal_get_data(j, "MESSAGE", &message, &len);
2646 if (r < 0) {
2647 if (r == -ENOENT) {
2648 need_seek = true;
2649 continue;
2650 }
2651
2652 log_error_errno(r, "Failed to get MESSAGE field: %m");
2653 goto finish;
2654 }
2655
2656 assert_se(message = startswith(message, "MESSAGE="));
2657
2658 r = pattern_matches_and_log(arg_compiled_pattern, message,
2659 len - strlen("MESSAGE="), highlight);
2660 if (r < 0)
2661 goto finish;
2662 if (r == 0) {
2663 need_seek = true;
2664 continue;
2665 }
2666 }
2667
2668 flags =
2669 arg_all * OUTPUT_SHOW_ALL |
2670 arg_full * OUTPUT_FULL_WIDTH |
2671 colors_enabled() * OUTPUT_COLOR |
2672 arg_catalog * OUTPUT_CATALOG |
2673 arg_utc * OUTPUT_UTC |
2674 arg_no_hostname * OUTPUT_NO_HOSTNAME;
2675
2676 r = show_journal_entry(stdout, j, arg_output, 0, flags,
2677 arg_output_fields, highlight, &ellipsized,
2678 &previous_ts_output, &previous_boot_id_output);
2679 need_seek = true;
2680 if (r == -EADDRNOTAVAIL)
2681 break;
2682 else if (r < 0)
2683 goto finish;
2684
2685 n_shown++;
2686
2687 /* If journalctl take a long time to process messages, and during that time journal file
2688 * rotation occurs, a journalctl client will keep those rotated files open until it calls
2689 * sd_journal_process(), which typically happens as a result of calling sd_journal_wait() below
2690 * in the "following" case. By periodically calling sd_journal_process() during the processing
2691 * loop we shrink the window of time a client instance has open file descriptors for rotated
2692 * (deleted) journal files. */
2693 if ((n_shown % PROCESS_INOTIFY_INTERVAL) == 0) {
2694 r = sd_journal_process(j);
2695 if (r < 0) {
2696 log_error_errno(r, "Failed to process inotify events: %m");
2697 goto finish;
2698 }
2699 }
2700 }
2701
2702 if (!arg_follow) {
2703 if (n_shown == 0 && !arg_quiet)
2704 printf("-- No entries --\n");
2705 break;
2706 }
2707
2708 fflush(stdout);
2709
2710 r = wait_for_change(j, poll_fd);
2711 if (r < 0)
2712 goto finish;
2713
2714 first_line = false;
2715 }
2716
2717 if (arg_show_cursor || arg_cursor_file) {
2718 _cleanup_free_ char *cursor = NULL;
2719
2720 r = sd_journal_get_cursor(j, &cursor);
2721 if (r < 0 && r != -EADDRNOTAVAIL)
2722 log_error_errno(r, "Failed to get cursor: %m");
2723 else if (r >= 0) {
2724 if (arg_show_cursor)
2725 printf("-- cursor: %s\n", cursor);
2726
2727 if (arg_cursor_file) {
2728 r = write_string_file(arg_cursor_file, cursor,
2729 WRITE_STRING_FILE_CREATE |
2730 WRITE_STRING_FILE_ATOMIC);
2731 if (r < 0)
2732 log_error_errno(r,
2733 "Failed to write new cursor to %s: %m",
2734 arg_cursor_file);
2735 }
2736 }
2737 }
2738
2739 finish:
2740 pager_close();
2741
2742 if (arg_compiled_pattern && r == 0 && n_shown == 0)
2743 /* --grep was used, no error was thrown, but the pattern didn't
2744 * match anything. Let's mimic grep's behavior here and return
2745 * a non-zero exit code, so journalctl --grep can be used
2746 * in scripts and such */
2747 r = -ENOENT;
2748
2749 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
2750 }