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