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