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