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