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