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