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