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