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