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