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