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