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