2 This file is part of systemd.
4 Copyright 2011 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
32 #include <sys/inotify.h>
37 #include "sd-journal.h"
40 #include "alloc-util.h"
41 #include "bus-error.h"
44 #include "chattr-util.h"
49 #include "glob-util.h"
50 #include "hostname-util.h"
52 #include "journal-def.h"
53 #include "journal-internal.h"
54 #include "journal-qrcode.h"
55 #include "journal-vacuum.h"
56 #include "journal-verify.h"
57 #include "locale-util.h"
59 #include "logs-show.h"
62 #include "parse-util.h"
63 #include "path-util.h"
64 #include "rlimit-util.h"
68 #include "syslog-util.h"
69 #include "terminal-util.h"
71 #include "udev-util.h"
72 #include "unit-name.h"
73 #include "user-util.h"
75 #define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
78 /* Special values for arg_lines */
79 ARG_LINES_DEFAULT
= -2,
83 static OutputMode arg_output
= OUTPUT_SHORT
;
84 static bool arg_utc
= false;
85 static bool arg_pager_end
= false;
86 static bool arg_follow
= false;
87 static bool arg_full
= true;
88 static bool arg_all
= false;
89 static bool arg_no_pager
= false;
90 static int arg_lines
= ARG_LINES_DEFAULT
;
91 static bool arg_no_tail
= false;
92 static bool arg_quiet
= false;
93 static bool arg_merge
= false;
94 static bool arg_boot
= false;
95 static sd_id128_t arg_boot_id
= {};
96 static int arg_boot_offset
= 0;
97 static bool arg_dmesg
= false;
98 static bool arg_no_hostname
= false;
99 static const char *arg_cursor
= NULL
;
100 static const char *arg_after_cursor
= NULL
;
101 static bool arg_show_cursor
= false;
102 static const char *arg_directory
= NULL
;
103 static char **arg_file
= NULL
;
104 static bool arg_file_stdin
= false;
105 static int arg_priorities
= 0xFF;
106 static const char *arg_verify_key
= NULL
;
108 static usec_t arg_interval
= DEFAULT_FSS_INTERVAL_USEC
;
109 static bool arg_force
= false;
111 static usec_t arg_since
, arg_until
;
112 static bool arg_since_set
= false, arg_until_set
= false;
113 static char **arg_syslog_identifier
= NULL
;
114 static char **arg_system_units
= NULL
;
115 static char **arg_user_units
= NULL
;
116 static const char *arg_field
= NULL
;
117 static bool arg_catalog
= false;
118 static bool arg_reverse
= false;
119 static int arg_journal_type
= 0;
120 static char *arg_root
= NULL
;
121 static const char *arg_machine
= NULL
;
122 static uint64_t arg_vacuum_size
= 0;
123 static uint64_t arg_vacuum_n_files
= 0;
124 static usec_t arg_vacuum_time
= 0;
135 ACTION_UPDATE_CATALOG
,
142 ACTION_LIST_FIELD_NAMES
,
143 } arg_action
= ACTION_SHOW
;
145 typedef struct BootId
{
149 LIST_FIELDS(struct BootId
, boot_list
);
152 static int add_matches_for_device(sd_journal
*j
, const char *devpath
) {
154 _cleanup_udev_unref_
struct udev
*udev
= NULL
;
155 _cleanup_udev_device_unref_
struct udev_device
*device
= NULL
;
156 struct udev_device
*d
= NULL
;
162 if (!path_startswith(devpath
, "/dev/")) {
163 log_error("Devpath does not start with /dev/");
171 r
= stat(devpath
, &st
);
173 log_error_errno(errno
, "Couldn't stat file: %m");
175 d
= device
= udev_device_new_from_devnum(udev
, S_ISBLK(st
.st_mode
) ? 'b' : 'c', st
.st_rdev
);
177 return log_error_errno(errno
, "Failed to get udev device from devnum %u:%u: %m", major(st
.st_rdev
), minor(st
.st_rdev
));
180 _cleanup_free_
char *match
= NULL
;
181 const char *subsys
, *sysname
, *devnode
;
183 subsys
= udev_device_get_subsystem(d
);
185 d
= udev_device_get_parent(d
);
189 sysname
= udev_device_get_sysname(d
);
191 d
= udev_device_get_parent(d
);
195 match
= strjoin("_KERNEL_DEVICE=+", subsys
, ":", sysname
);
199 r
= sd_journal_add_match(j
, match
, 0);
201 return log_error_errno(r
, "Failed to add match: %m");
203 devnode
= udev_device_get_devnode(d
);
205 _cleanup_free_
char *match1
= NULL
;
207 r
= stat(devnode
, &st
);
209 return log_error_errno(r
, "Failed to stat() device node \"%s\": %m", devnode
);
211 r
= asprintf(&match1
, "_KERNEL_DEVICE=%c%u:%u", S_ISBLK(st
.st_mode
) ? 'b' : 'c', major(st
.st_rdev
), minor(st
.st_rdev
));
215 r
= sd_journal_add_match(j
, match1
, 0);
217 return log_error_errno(r
, "Failed to add match: %m");
220 d
= udev_device_get_parent(d
);
223 r
= add_match_this_boot(j
, arg_machine
);
225 return log_error_errno(r
, "Failed to add match for the current boot: %m");
230 static char *format_timestamp_maybe_utc(char *buf
, size_t l
, usec_t t
) {
233 return format_timestamp_utc(buf
, l
, t
);
235 return format_timestamp(buf
, l
, t
);
238 static int parse_boot_descriptor(const char *x
, sd_id128_t
*boot_id
, int *offset
) {
239 sd_id128_t id
= SD_ID128_NULL
;
242 if (strlen(x
) >= 32) {
246 r
= sd_id128_from_string(t
, &id
);
250 if (*x
!= '-' && *x
!= '+' && *x
!= 0)
254 r
= safe_atoi(x
, &off
);
259 r
= safe_atoi(x
, &off
);
273 static void help(void) {
275 pager_open(arg_no_pager
, arg_pager_end
);
277 printf("%s [OPTIONS...] [MATCHES...]\n\n"
278 "Query the journal.\n\n"
280 " --system Show the system journal\n"
281 " --user Show the user journal for the current user\n"
282 " -M --machine=CONTAINER Operate on local container\n"
283 " -S --since=DATE Show entries not older than the specified date\n"
284 " -U --until=DATE Show entries not newer than the specified date\n"
285 " -c --cursor=CURSOR Show entries starting at the specified cursor\n"
286 " --after-cursor=CURSOR Show entries after the specified cursor\n"
287 " --show-cursor Print the cursor after all the entries\n"
288 " -b --boot[=ID] Show current boot or the specified boot\n"
289 " --list-boots Show terse information about recorded boots\n"
290 " -k --dmesg Show kernel message log from the current boot\n"
291 " -u --unit=UNIT Show logs from the specified unit\n"
292 " --user-unit=UNIT Show logs from the specified user unit\n"
293 " -t --identifier=STRING Show entries with the specified syslog identifier\n"
294 " -p --priority=RANGE Show entries with the specified priority\n"
295 " -e --pager-end Immediately jump to the end in the pager\n"
296 " -f --follow Follow the journal\n"
297 " -n --lines[=INTEGER] Number of journal entries to show\n"
298 " --no-tail Show all lines, even in follow mode\n"
299 " -r --reverse Show the newest entries first\n"
300 " -o --output=STRING Change journal output mode (short, short-precise,\n"
301 " short-iso, short-full, short-monotonic, short-unix,\n"
302 " verbose, export, json, json-pretty, json-sse, cat)\n"
303 " --utc Express time in Coordinated Universal Time (UTC)\n"
304 " -x --catalog Add message explanations where available\n"
305 " --no-full Ellipsize fields\n"
306 " -a --all Show all fields, including long and unprintable\n"
307 " -q --quiet Do not show info messages and privilege warning\n"
308 " --no-pager Do not pipe output into a pager\n"
309 " --no-hostname Suppress output of hostname field\n"
310 " -m --merge Show entries from all available journals\n"
311 " -D --directory=PATH Show journal files from directory\n"
312 " --file=PATH Show journal file\n"
313 " --root=ROOT Operate on files below a root directory\n"
315 " --interval=TIME Time interval for changing the FSS sealing key\n"
316 " --verify-key=KEY Specify FSS verification key\n"
317 " --force Override of the FSS key pair with --setup-keys\n"
320 " -h --help Show this help text\n"
321 " --version Show package version\n"
322 " -N --fields List all field names currently used\n"
323 " -F --field=FIELD List all values that a specified field takes\n"
324 " --disk-usage Show total disk usage of all journal files\n"
325 " --vacuum-size=BYTES Reduce disk usage below specified size\n"
326 " --vacuum-files=INT Leave only the specified number of journal files\n"
327 " --vacuum-time=TIME Remove journal files older than specified time\n"
328 " --verify Verify journal file consistency\n"
329 " --sync Synchronize unwritten journal messages to disk\n"
330 " --flush Flush all journal data from /run into /var\n"
331 " --rotate Request immediate rotation of the journal files\n"
332 " --header Show journal header information\n"
333 " --list-catalog Show all message IDs in the catalog\n"
334 " --dump-catalog Show entries in the message catalog\n"
335 " --update-catalog Update the message catalog database\n"
336 " --new-id128 Generate a new 128-bit ID\n"
338 " --setup-keys Generate a new FSS key pair\n"
340 , program_invocation_short_name
);
343 static int parse_argv(int argc
, char *argv
[]) {
380 static const struct option options
[] = {
381 { "help", no_argument
, NULL
, 'h' },
382 { "version" , no_argument
, NULL
, ARG_VERSION
},
383 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
384 { "pager-end", no_argument
, NULL
, 'e' },
385 { "follow", no_argument
, NULL
, 'f' },
386 { "force", no_argument
, NULL
, ARG_FORCE
},
387 { "output", required_argument
, NULL
, 'o' },
388 { "all", no_argument
, NULL
, 'a' },
389 { "full", no_argument
, NULL
, 'l' },
390 { "no-full", no_argument
, NULL
, ARG_NO_FULL
},
391 { "lines", optional_argument
, NULL
, 'n' },
392 { "no-tail", no_argument
, NULL
, ARG_NO_TAIL
},
393 { "new-id128", no_argument
, NULL
, ARG_NEW_ID128
},
394 { "quiet", no_argument
, NULL
, 'q' },
395 { "merge", no_argument
, NULL
, 'm' },
396 { "this-boot", no_argument
, NULL
, ARG_THIS_BOOT
}, /* deprecated */
397 { "boot", optional_argument
, NULL
, 'b' },
398 { "list-boots", no_argument
, NULL
, ARG_LIST_BOOTS
},
399 { "dmesg", no_argument
, NULL
, 'k' },
400 { "system", no_argument
, NULL
, ARG_SYSTEM
},
401 { "user", no_argument
, NULL
, ARG_USER
},
402 { "directory", required_argument
, NULL
, 'D' },
403 { "file", required_argument
, NULL
, ARG_FILE
},
404 { "root", required_argument
, NULL
, ARG_ROOT
},
405 { "header", no_argument
, NULL
, ARG_HEADER
},
406 { "identifier", required_argument
, NULL
, 't' },
407 { "priority", required_argument
, NULL
, 'p' },
408 { "setup-keys", no_argument
, NULL
, ARG_SETUP_KEYS
},
409 { "interval", required_argument
, NULL
, ARG_INTERVAL
},
410 { "verify", no_argument
, NULL
, ARG_VERIFY
},
411 { "verify-key", required_argument
, NULL
, ARG_VERIFY_KEY
},
412 { "disk-usage", no_argument
, NULL
, ARG_DISK_USAGE
},
413 { "cursor", required_argument
, NULL
, 'c' },
414 { "after-cursor", required_argument
, NULL
, ARG_AFTER_CURSOR
},
415 { "show-cursor", no_argument
, NULL
, ARG_SHOW_CURSOR
},
416 { "since", required_argument
, NULL
, 'S' },
417 { "until", required_argument
, NULL
, 'U' },
418 { "unit", required_argument
, NULL
, 'u' },
419 { "user-unit", required_argument
, NULL
, ARG_USER_UNIT
},
420 { "field", required_argument
, NULL
, 'F' },
421 { "fields", no_argument
, NULL
, 'N' },
422 { "catalog", no_argument
, NULL
, 'x' },
423 { "list-catalog", no_argument
, NULL
, ARG_LIST_CATALOG
},
424 { "dump-catalog", no_argument
, NULL
, ARG_DUMP_CATALOG
},
425 { "update-catalog", no_argument
, NULL
, ARG_UPDATE_CATALOG
},
426 { "reverse", no_argument
, NULL
, 'r' },
427 { "machine", required_argument
, NULL
, 'M' },
428 { "utc", no_argument
, NULL
, ARG_UTC
},
429 { "flush", no_argument
, NULL
, ARG_FLUSH
},
430 { "sync", no_argument
, NULL
, ARG_SYNC
},
431 { "rotate", no_argument
, NULL
, ARG_ROTATE
},
432 { "vacuum-size", required_argument
, NULL
, ARG_VACUUM_SIZE
},
433 { "vacuum-files", required_argument
, NULL
, ARG_VACUUM_FILES
},
434 { "vacuum-time", required_argument
, NULL
, ARG_VACUUM_TIME
},
435 { "no-hostname", no_argument
, NULL
, ARG_NO_HOSTNAME
},
444 while ((c
= getopt_long(argc
, argv
, "hefo:aln::qmb::kD:p:c:S:U:t:u:NF:xrM:", options
, NULL
)) >= 0)
460 arg_pager_end
= true;
462 if (arg_lines
== ARG_LINES_DEFAULT
)
472 arg_output
= output_mode_from_string(optarg
);
473 if (arg_output
< 0) {
474 log_error("Unknown output format '%s'.", optarg
);
478 if (arg_output
== OUTPUT_EXPORT
||
479 arg_output
== OUTPUT_JSON
||
480 arg_output
== OUTPUT_JSON_PRETTY
||
481 arg_output
== OUTPUT_JSON_SSE
||
482 arg_output
== OUTPUT_CAT
)
501 if (streq(optarg
, "all"))
502 arg_lines
= ARG_LINES_ALL
;
504 r
= safe_atoi(optarg
, &arg_lines
);
505 if (r
< 0 || arg_lines
< 0) {
506 log_error("Failed to parse lines '%s'", optarg
);
513 /* Hmm, no argument? Maybe the next
514 * word on the command line is
515 * supposed to be the argument? Let's
516 * see if there is one, and is
520 if (streq(argv
[optind
], "all")) {
521 arg_lines
= ARG_LINES_ALL
;
523 } else if (safe_atoi(argv
[optind
], &n
) >= 0 && n
>= 0) {
537 arg_action
= ACTION_NEW_ID128
;
556 r
= parse_boot_descriptor(optarg
, &arg_boot_id
, &arg_boot_offset
);
558 log_error("Failed to parse boot descriptor '%s'", optarg
);
563 /* Hmm, no argument? Maybe the next
564 * word on the command line is
565 * supposed to be the argument? Let's
566 * see if there is one and is parsable
567 * as a boot descriptor... */
570 parse_boot_descriptor(argv
[optind
], &arg_boot_id
, &arg_boot_offset
) >= 0)
577 arg_action
= ACTION_LIST_BOOTS
;
581 arg_boot
= arg_dmesg
= true;
585 arg_journal_type
|= SD_JOURNAL_SYSTEM
;
589 arg_journal_type
|= SD_JOURNAL_CURRENT_USER
;
593 arg_machine
= optarg
;
597 arg_directory
= optarg
;
601 if (streq(optarg
, "-"))
602 /* An undocumented feature: we can read journal files from STDIN. We don't document
603 * this though, since after all we only support this for mmap-able, seekable files, and
604 * not for example pipes which are probably the primary usecase for reading things from
605 * STDIN. To avoid confusion we hence don't document this feature. */
606 arg_file_stdin
= true;
608 r
= glob_extend(&arg_file
, optarg
);
610 return log_error_errno(r
, "Failed to add paths: %m");
615 r
= parse_path_argument_and_warn(optarg
, true, &arg_root
);
624 case ARG_AFTER_CURSOR
:
625 arg_after_cursor
= optarg
;
628 case ARG_SHOW_CURSOR
:
629 arg_show_cursor
= true;
633 arg_action
= ACTION_PRINT_HEADER
;
637 arg_action
= ACTION_VERIFY
;
641 arg_action
= ACTION_DISK_USAGE
;
644 case ARG_VACUUM_SIZE
:
645 r
= parse_size(optarg
, 1024, &arg_vacuum_size
);
647 log_error("Failed to parse vacuum size: %s", optarg
);
651 arg_action
= ACTION_VACUUM
;
654 case ARG_VACUUM_FILES
:
655 r
= safe_atou64(optarg
, &arg_vacuum_n_files
);
657 log_error("Failed to parse vacuum files: %s", optarg
);
661 arg_action
= ACTION_VACUUM
;
664 case ARG_VACUUM_TIME
:
665 r
= parse_sec(optarg
, &arg_vacuum_time
);
667 log_error("Failed to parse vacuum time: %s", optarg
);
671 arg_action
= ACTION_VACUUM
;
680 arg_action
= ACTION_SETUP_KEYS
;
685 arg_action
= ACTION_VERIFY
;
686 arg_verify_key
= optarg
;
691 r
= parse_sec(optarg
, &arg_interval
);
692 if (r
< 0 || arg_interval
<= 0) {
693 log_error("Failed to parse sealing key change interval: %s", optarg
);
702 log_error("Forward-secure sealing not available.");
709 dots
= strstr(optarg
, "..");
715 a
= strndup(optarg
, dots
- optarg
);
719 from
= log_level_from_string(a
);
720 to
= log_level_from_string(dots
+ 2);
723 if (from
< 0 || to
< 0) {
724 log_error("Failed to parse log level range %s", optarg
);
731 for (i
= from
; i
<= to
; i
++)
732 arg_priorities
|= 1 << i
;
734 for (i
= to
; i
<= from
; i
++)
735 arg_priorities
|= 1 << i
;
741 p
= log_level_from_string(optarg
);
743 log_error("Unknown log level %s", optarg
);
749 for (i
= 0; i
<= p
; i
++)
750 arg_priorities
|= 1 << i
;
757 r
= parse_timestamp(optarg
, &arg_since
);
759 log_error("Failed to parse timestamp: %s", optarg
);
762 arg_since_set
= true;
766 r
= parse_timestamp(optarg
, &arg_until
);
768 log_error("Failed to parse timestamp: %s", optarg
);
771 arg_until_set
= true;
775 r
= strv_extend(&arg_syslog_identifier
, optarg
);
781 r
= strv_extend(&arg_system_units
, optarg
);
787 r
= strv_extend(&arg_user_units
, optarg
);
793 arg_action
= ACTION_LIST_FIELDS
;
798 arg_action
= ACTION_LIST_FIELD_NAMES
;
801 case ARG_NO_HOSTNAME
:
802 arg_no_hostname
= true;
809 case ARG_LIST_CATALOG
:
810 arg_action
= ACTION_LIST_CATALOG
;
813 case ARG_DUMP_CATALOG
:
814 arg_action
= ACTION_DUMP_CATALOG
;
817 case ARG_UPDATE_CATALOG
:
818 arg_action
= ACTION_UPDATE_CATALOG
;
830 arg_action
= ACTION_FLUSH
;
834 arg_action
= ACTION_ROTATE
;
838 arg_action
= ACTION_SYNC
;
845 assert_not_reached("Unhandled option");
848 if (arg_follow
&& !arg_no_tail
&& !arg_since
&& arg_lines
== ARG_LINES_DEFAULT
)
851 if (!!arg_directory
+ !!arg_file
+ !!arg_machine
+ !!arg_root
> 1) {
852 log_error("Please specify at most one of -D/--directory=, --file=, -M/--machine=, --root.");
856 if (arg_since_set
&& arg_until_set
&& arg_since
> arg_until
) {
857 log_error("--since= must be before --until=.");
861 if (!!arg_cursor
+ !!arg_after_cursor
+ !!arg_since_set
> 1) {
862 log_error("Please specify only one of --since=, --cursor=, and --after-cursor.");
866 if (arg_follow
&& arg_reverse
) {
867 log_error("Please specify either --reverse= or --follow=, not both.");
871 if (!IN_SET(arg_action
, ACTION_SHOW
, ACTION_DUMP_CATALOG
, ACTION_LIST_CATALOG
) && optind
< argc
) {
872 log_error("Extraneous arguments starting with '%s'", argv
[optind
]);
876 if ((arg_boot
|| arg_action
== ACTION_LIST_BOOTS
) && arg_merge
) {
877 log_error("Using --boot or --list-boots with --merge is not supported.");
881 if (!strv_isempty(arg_system_units
) && (arg_journal_type
== SD_JOURNAL_CURRENT_USER
)) {
883 /* Specifying --user and --unit= at the same time makes no sense (as the former excludes the user
884 * journal, but the latter excludes the system journal, thus resulting in empty output). Let's be nice
885 * to users, and automatically turn --unit= into --user-unit= if combined with --user. */
886 r
= strv_extend_strv(&arg_user_units
, arg_system_units
, true);
890 arg_system_units
= strv_free(arg_system_units
);
896 static int generate_new_id128(void) {
901 r
= sd_id128_randomize(&id
);
903 return log_error_errno(r
, "Failed to generate ID: %m");
905 printf("As string:\n"
906 SD_ID128_FORMAT_STR
"\n\n"
908 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n"
910 "#define MESSAGE_XYZ SD_ID128_MAKE(",
911 SD_ID128_FORMAT_VAL(id
),
912 SD_ID128_FORMAT_VAL(id
));
913 for (i
= 0; i
< 16; i
++)
914 printf("%02x%s", id
.bytes
[i
], i
!= 15 ? "," : "");
915 fputs(")\n\n", stdout
);
917 printf("As Python constant:\n"
919 ">>> MESSAGE_XYZ = uuid.UUID('" SD_ID128_FORMAT_STR
"')\n",
920 SD_ID128_FORMAT_VAL(id
));
925 static int add_matches(sd_journal
*j
, char **args
) {
927 bool have_term
= false;
931 STRV_FOREACH(i
, args
) {
934 if (streq(*i
, "+")) {
937 r
= sd_journal_add_disjunction(j
);
940 } else if (path_is_absolute(*i
)) {
941 _cleanup_free_
char *p
= NULL
, *t
= NULL
, *t2
= NULL
, *interpreter
= NULL
;
944 r
= chase_symlinks(*i
, NULL
, &p
);
946 return log_error_errno(r
, "Couldn't canonicalize path: %m");
948 if (lstat(p
, &st
) < 0)
949 return log_error_errno(errno
, "Couldn't stat file: %m");
951 if (S_ISREG(st
.st_mode
) && (0111 & st
.st_mode
)) {
952 if (executable_is_script(p
, &interpreter
) > 0) {
953 _cleanup_free_
char *comm
;
955 comm
= strndup(basename(p
), 15);
959 t
= strappend("_COMM=", comm
);
963 /* Append _EXE only if the interpreter is not a link.
964 Otherwise, it might be outdated often. */
965 if (lstat(interpreter
, &st
) == 0 && !S_ISLNK(st
.st_mode
)) {
966 t2
= strappend("_EXE=", interpreter
);
971 t
= strappend("_EXE=", p
);
976 r
= sd_journal_add_match(j
, t
, 0);
979 r
= sd_journal_add_match(j
, t2
, 0);
981 } else if (S_ISCHR(st
.st_mode
) || S_ISBLK(st
.st_mode
)) {
982 r
= add_matches_for_device(j
, p
);
986 log_error("File is neither a device node, nor regular file, nor executable: %s", *i
);
992 r
= sd_journal_add_match(j
, *i
, 0);
997 return log_error_errno(r
, "Failed to add match '%s': %m", *i
);
1000 if (!strv_isempty(args
) && !have_term
) {
1001 log_error("\"+\" can only be used between terms");
1008 static void boot_id_free_all(BootId
*l
) {
1012 LIST_REMOVE(boot_list
, l
, i
);
1017 static int discover_next_boot(sd_journal
*j
,
1018 sd_id128_t previous_boot_id
,
1022 _cleanup_free_ BootId
*next_boot
= NULL
;
1023 char match
[9+32+1] = "_BOOT_ID=";
1030 /* We expect the journal to be on the last position of a boot
1031 * (in relation to the direction we are going), so that the next
1032 * invocation of sd_journal_next/previous will be from a different
1033 * boot. We then collect any information we desire and then jump
1034 * to the last location of the new boot by using a _BOOT_ID match
1035 * coming from the other journal direction. */
1037 /* Make sure we aren't restricted by any _BOOT_ID matches, so that
1038 * we can actually advance to a *different* boot. */
1039 sd_journal_flush_matches(j
);
1043 r
= sd_journal_previous(j
);
1045 r
= sd_journal_next(j
);
1049 return 0; /* End of journal, yay. */
1051 r
= sd_journal_get_monotonic_usec(j
, NULL
, &boot_id
);
1055 /* We iterate through this in a loop, until the boot ID differs from the previous one. Note that
1056 * normally, this will only require a single iteration, as we seeked to the last entry of the previous
1057 * boot entry already. However, it might happen that the per-journal-field entry arrays are less
1058 * complete than the main entry array, and hence might reference an entry that's not actually the last
1059 * one of the boot ID as last one. Let's hence use the per-field array is initial seek position to
1060 * speed things up, but let's not trust that it is complete, and hence, manually advance as
1063 } while (sd_id128_equal(boot_id
, previous_boot_id
));
1065 next_boot
= new0(BootId
, 1);
1069 next_boot
->id
= boot_id
;
1071 r
= sd_journal_get_realtime_usec(j
, &next_boot
->first
);
1075 /* Now seek to the last occurrence of this boot ID. */
1076 sd_id128_to_string(next_boot
->id
, match
+ 9);
1077 r
= sd_journal_add_match(j
, match
, sizeof(match
) - 1);
1082 r
= sd_journal_seek_head(j
);
1084 r
= sd_journal_seek_tail(j
);
1089 r
= sd_journal_next(j
);
1091 r
= sd_journal_previous(j
);
1095 log_debug("Whoopsie! We found a boot ID but can't read its last entry.");
1096 return -ENODATA
; /* This shouldn't happen. We just came from this very boot ID. */
1099 r
= sd_journal_get_realtime_usec(j
, &next_boot
->last
);
1109 static int get_boots(
1112 sd_id128_t
*boot_id
,
1117 BootId
*head
= NULL
, *tail
= NULL
, *id
;
1118 const bool advance_older
= boot_id
&& offset
<= 0;
1119 sd_id128_t previous_boot_id
;
1123 /* Adjust for the asymmetry that offset 0 is
1124 * the last (and current) boot, while 1 is considered the
1125 * (chronological) first boot in the journal. */
1126 skip_once
= boot_id
&& sd_id128_is_null(*boot_id
) && offset
<= 0;
1128 /* Advance to the earliest/latest occurrence of our reference
1129 * boot ID (taking our lookup direction into account), so that
1130 * discover_next_boot() can do its job.
1131 * If no reference is given, the journal head/tail will do,
1132 * they're "virtual" boots after all. */
1133 if (boot_id
&& !sd_id128_is_null(*boot_id
)) {
1134 char match
[9+32+1] = "_BOOT_ID=";
1136 sd_journal_flush_matches(j
);
1138 sd_id128_to_string(*boot_id
, match
+ 9);
1139 r
= sd_journal_add_match(j
, match
, sizeof(match
) - 1);
1144 r
= sd_journal_seek_head(j
); /* seek to oldest */
1146 r
= sd_journal_seek_tail(j
); /* seek to newest */
1151 r
= sd_journal_next(j
); /* read the oldest entry */
1153 r
= sd_journal_previous(j
); /* read the most recently added entry */
1158 else if (offset
== 0) {
1163 /* At this point the read pointer is positioned at the oldest/newest occurence of the reference boot
1164 * ID. After flushing the matches, one more invocation of _previous()/_next() will hence place us at
1165 * the following entry, which must then have an older/newer boot ID */
1169 r
= sd_journal_seek_tail(j
); /* seek to newest */
1171 r
= sd_journal_seek_head(j
); /* seek to oldest */
1175 /* No sd_journal_next()/_previous() here.
1177 * At this point the read pointer is positioned after the newest/before the oldest entry in the whole
1178 * journal. The next invocation of _previous()/_next() will hence position us at the newest/oldest
1182 previous_boot_id
= SD_ID128_NULL
;
1184 _cleanup_free_ BootId
*current
= NULL
;
1186 r
= discover_next_boot(j
, previous_boot_id
, advance_older
, ¤t
);
1188 boot_id_free_all(head
);
1195 previous_boot_id
= current
->id
;
1199 offset
+= advance_older
? 1 : -1;
1204 *boot_id
= current
->id
;
1208 LIST_FOREACH(boot_list
, id
, head
) {
1209 if (sd_id128_equal(id
->id
, current
->id
)) {
1210 /* boot id already stored, something wrong with the journal files */
1211 /* exiting as otherwise this problem would cause forever loop */
1215 LIST_INSERT_AFTER(boot_list
, head
, tail
, current
);
1226 sd_journal_flush_matches(j
);
1231 static int list_boots(sd_journal
*j
) {
1233 BootId
*id
, *all_ids
;
1237 count
= get_boots(j
, &all_ids
, NULL
, 0);
1239 return log_error_errno(count
, "Failed to determine boots: %m");
1243 pager_open(arg_no_pager
, arg_pager_end
);
1245 /* numbers are one less, but we need an extra char for the sign */
1246 w
= DECIMAL_STR_WIDTH(count
- 1) + 1;
1249 LIST_FOREACH(boot_list
, id
, all_ids
) {
1250 char a
[FORMAT_TIMESTAMP_MAX
], b
[FORMAT_TIMESTAMP_MAX
];
1252 printf("% *i " SD_ID128_FORMAT_STR
" %s—%s\n",
1254 SD_ID128_FORMAT_VAL(id
->id
),
1255 format_timestamp_maybe_utc(a
, sizeof(a
), id
->first
),
1256 format_timestamp_maybe_utc(b
, sizeof(b
), id
->last
));
1260 boot_id_free_all(all_ids
);
1265 static int add_boot(sd_journal
*j
) {
1266 char match
[9+32+1] = "_BOOT_ID=";
1275 /* Take a shortcut and use the current boot_id, which we can do very quickly.
1276 * We can do this only when we logs are coming from the current machine,
1277 * so take the slow path if log location is specified. */
1278 if (arg_boot_offset
== 0 && sd_id128_is_null(arg_boot_id
) &&
1279 !arg_directory
&& !arg_file
&& !arg_root
)
1281 return add_match_this_boot(j
, arg_machine
);
1283 boot_id
= arg_boot_id
;
1284 r
= get_boots(j
, NULL
, &boot_id
, arg_boot_offset
);
1287 const char *reason
= (r
== 0) ? "No such boot ID in journal" : strerror(-r
);
1289 if (sd_id128_is_null(arg_boot_id
))
1290 log_error("Data from the specified boot (%+i) is not available: %s",
1291 arg_boot_offset
, reason
);
1293 log_error("Data from the specified boot ("SD_ID128_FORMAT_STR
") is not available: %s",
1294 SD_ID128_FORMAT_VAL(arg_boot_id
), reason
);
1296 return r
== 0 ? -ENODATA
: r
;
1299 sd_id128_to_string(boot_id
, match
+ 9);
1301 r
= sd_journal_add_match(j
, match
, sizeof(match
) - 1);
1303 return log_error_errno(r
, "Failed to add match: %m");
1305 r
= sd_journal_add_conjunction(j
);
1307 return log_error_errno(r
, "Failed to add conjunction: %m");
1312 static int add_dmesg(sd_journal
*j
) {
1319 r
= sd_journal_add_match(j
, "_TRANSPORT=kernel", strlen("_TRANSPORT=kernel"));
1321 return log_error_errno(r
, "Failed to add match: %m");
1323 r
= sd_journal_add_conjunction(j
);
1325 return log_error_errno(r
, "Failed to add conjunction: %m");
1330 static int get_possible_units(
1336 _cleanup_set_free_free_ Set
*found
;
1340 found
= set_new(&string_hash_ops
);
1344 NULSTR_FOREACH(field
, fields
) {
1348 r
= sd_journal_query_unique(j
, field
);
1352 SD_JOURNAL_FOREACH_UNIQUE(j
, data
, size
) {
1353 char **pattern
, *eq
;
1355 _cleanup_free_
char *u
= NULL
;
1357 eq
= memchr(data
, '=', size
);
1359 prefix
= eq
- (char*) data
+ 1;
1363 u
= strndup((char*) data
+ prefix
, size
- prefix
);
1367 STRV_FOREACH(pattern
, patterns
)
1368 if (fnmatch(*pattern
, u
, FNM_NOESCAPE
) == 0) {
1369 log_debug("Matched %s with pattern %s=%s", u
, field
, *pattern
);
1371 r
= set_consume(found
, u
);
1373 if (r
< 0 && r
!= -EEXIST
)
1386 /* This list is supposed to return the superset of unit names
1387 * possibly matched by rules added with add_matches_for_unit... */
1388 #define SYSTEM_UNITS \
1392 "OBJECT_SYSTEMD_UNIT\0" \
1395 /* ... and add_matches_for_user_unit */
1396 #define USER_UNITS \
1397 "_SYSTEMD_USER_UNIT\0" \
1399 "COREDUMP_USER_UNIT\0" \
1400 "OBJECT_SYSTEMD_USER_UNIT\0"
1402 static int add_units(sd_journal
*j
) {
1403 _cleanup_strv_free_
char **patterns
= NULL
;
1409 STRV_FOREACH(i
, arg_system_units
) {
1410 _cleanup_free_
char *u
= NULL
;
1412 r
= unit_name_mangle(*i
, UNIT_NAME_GLOB
, &u
);
1416 if (string_is_glob(u
)) {
1417 r
= strv_push(&patterns
, u
);
1422 r
= add_matches_for_unit(j
, u
);
1425 r
= sd_journal_add_disjunction(j
);
1432 if (!strv_isempty(patterns
)) {
1433 _cleanup_set_free_free_ Set
*units
= NULL
;
1437 r
= get_possible_units(j
, SYSTEM_UNITS
, patterns
, &units
);
1441 SET_FOREACH(u
, units
, it
) {
1442 r
= add_matches_for_unit(j
, u
);
1445 r
= sd_journal_add_disjunction(j
);
1452 patterns
= strv_free(patterns
);
1454 STRV_FOREACH(i
, arg_user_units
) {
1455 _cleanup_free_
char *u
= NULL
;
1457 r
= unit_name_mangle(*i
, UNIT_NAME_GLOB
, &u
);
1461 if (string_is_glob(u
)) {
1462 r
= strv_push(&patterns
, u
);
1467 r
= add_matches_for_user_unit(j
, u
, getuid());
1470 r
= sd_journal_add_disjunction(j
);
1477 if (!strv_isempty(patterns
)) {
1478 _cleanup_set_free_free_ Set
*units
= NULL
;
1482 r
= get_possible_units(j
, USER_UNITS
, patterns
, &units
);
1486 SET_FOREACH(u
, units
, it
) {
1487 r
= add_matches_for_user_unit(j
, u
, getuid());
1490 r
= sd_journal_add_disjunction(j
);
1497 /* Complain if the user request matches but nothing whatsoever was
1498 * found, since otherwise everything would be matched. */
1499 if (!(strv_isempty(arg_system_units
) && strv_isempty(arg_user_units
)) && count
== 0)
1502 r
= sd_journal_add_conjunction(j
);
1509 static int add_priorities(sd_journal
*j
) {
1510 char match
[] = "PRIORITY=0";
1514 if (arg_priorities
== 0xFF)
1517 for (i
= LOG_EMERG
; i
<= LOG_DEBUG
; i
++)
1518 if (arg_priorities
& (1 << i
)) {
1519 match
[sizeof(match
)-2] = '0' + i
;
1521 r
= sd_journal_add_match(j
, match
, strlen(match
));
1523 return log_error_errno(r
, "Failed to add match: %m");
1526 r
= sd_journal_add_conjunction(j
);
1528 return log_error_errno(r
, "Failed to add conjunction: %m");
1534 static int add_syslog_identifier(sd_journal
*j
) {
1540 STRV_FOREACH(i
, arg_syslog_identifier
) {
1543 u
= strjoina("SYSLOG_IDENTIFIER=", *i
);
1544 r
= sd_journal_add_match(j
, u
, 0);
1547 r
= sd_journal_add_disjunction(j
);
1552 r
= sd_journal_add_conjunction(j
);
1559 static int setup_keys(void) {
1561 size_t mpk_size
, seed_size
, state_size
, i
;
1562 uint8_t *mpk
, *seed
, *state
;
1564 sd_id128_t machine
, boot
;
1565 char *p
= NULL
, *k
= NULL
;
1570 r
= stat("/var/log/journal", &st
);
1571 if (r
< 0 && errno
!= ENOENT
&& errno
!= ENOTDIR
)
1572 return log_error_errno(errno
, "stat(\"%s\") failed: %m", "/var/log/journal");
1574 if (r
< 0 || !S_ISDIR(st
.st_mode
)) {
1575 log_error("%s is not a directory, must be using persistent logging for FSS.",
1576 "/var/log/journal");
1577 return r
< 0 ? -errno
: -ENOTDIR
;
1580 r
= sd_id128_get_machine(&machine
);
1582 return log_error_errno(r
, "Failed to get machine ID: %m");
1584 r
= sd_id128_get_boot(&boot
);
1586 return log_error_errno(r
, "Failed to get boot ID: %m");
1588 if (asprintf(&p
, "/var/log/journal/" SD_ID128_FORMAT_STR
"/fss",
1589 SD_ID128_FORMAT_VAL(machine
)) < 0)
1594 if (r
< 0 && errno
!= ENOENT
) {
1595 r
= log_error_errno(errno
, "unlink(\"%s\") failed: %m", p
);
1598 } else if (access(p
, F_OK
) >= 0) {
1599 log_error("Sealing key file %s exists already. Use --force to recreate.", p
);
1604 if (asprintf(&k
, "/var/log/journal/" SD_ID128_FORMAT_STR
"/fss.tmp.XXXXXX",
1605 SD_ID128_FORMAT_VAL(machine
)) < 0) {
1610 mpk_size
= FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR
);
1611 mpk
= alloca(mpk_size
);
1613 seed_size
= FSPRG_RECOMMENDED_SEEDLEN
;
1614 seed
= alloca(seed_size
);
1616 state_size
= FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR
);
1617 state
= alloca(state_size
);
1619 fd
= open("/dev/random", O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
1621 r
= log_error_errno(errno
, "Failed to open /dev/random: %m");
1625 log_info("Generating seed...");
1626 r
= loop_read_exact(fd
, seed
, seed_size
, true);
1628 log_error_errno(r
, "Failed to read random seed: %m");
1632 log_info("Generating key pair...");
1633 FSPRG_GenMK(NULL
, mpk
, seed
, seed_size
, FSPRG_RECOMMENDED_SECPAR
);
1635 log_info("Generating sealing key...");
1636 FSPRG_GenState0(state
, mpk
, seed
, seed_size
);
1638 assert(arg_interval
> 0);
1640 n
= now(CLOCK_REALTIME
);
1644 fd
= mkostemp_safe(k
);
1646 r
= log_error_errno(fd
, "Failed to open %s: %m", k
);
1650 /* Enable secure remove, exclusion from dump, synchronous
1651 * writing and in-place updating */
1652 r
= chattr_fd(fd
, FS_SECRM_FL
|FS_NODUMP_FL
|FS_SYNC_FL
|FS_NOCOW_FL
, FS_SECRM_FL
|FS_NODUMP_FL
|FS_SYNC_FL
|FS_NOCOW_FL
);
1654 log_warning_errno(r
, "Failed to set file attributes: %m");
1657 memcpy(h
.signature
, "KSHHRHLP", 8);
1658 h
.machine_id
= machine
;
1660 h
.header_size
= htole64(sizeof(h
));
1661 h
.start_usec
= htole64(n
* arg_interval
);
1662 h
.interval_usec
= htole64(arg_interval
);
1663 h
.fsprg_secpar
= htole16(FSPRG_RECOMMENDED_SECPAR
);
1664 h
.fsprg_state_size
= htole64(state_size
);
1666 r
= loop_write(fd
, &h
, sizeof(h
), false);
1668 log_error_errno(r
, "Failed to write header: %m");
1672 r
= loop_write(fd
, state
, state_size
, false);
1674 log_error_errno(r
, "Failed to write state: %m");
1678 if (link(k
, p
) < 0) {
1679 r
= log_error_errno(errno
, "Failed to link file: %m");
1686 "The new key pair has been generated. The %ssecret sealing key%s has been written to\n"
1687 "the following local file. This key file is automatically updated when the\n"
1688 "sealing key is advanced. It should not be used on multiple hosts.\n"
1692 "Please write down the following %ssecret verification key%s. It should be stored\n"
1693 "at a safe location and should not be saved locally on disk.\n"
1695 ansi_highlight(), ansi_normal(),
1697 ansi_highlight(), ansi_normal(),
1698 ansi_highlight_red());
1701 for (i
= 0; i
< seed_size
; i
++) {
1702 if (i
> 0 && i
% 3 == 0)
1704 printf("%02x", ((uint8_t*) seed
)[i
]);
1707 printf("/%llx-%llx\n", (unsigned long long) n
, (unsigned long long) arg_interval
);
1710 char tsb
[FORMAT_TIMESPAN_MAX
], *hn
;
1714 "The sealing key is automatically changed every %s.\n",
1716 format_timespan(tsb
, sizeof(tsb
), arg_interval
, 0));
1718 hn
= gethostname_malloc();
1721 hostname_cleanup(hn
);
1722 fprintf(stderr
, "\nThe keys have been generated for host %s/" SD_ID128_FORMAT_STR
".\n", hn
, SD_ID128_FORMAT_VAL(machine
));
1724 fprintf(stderr
, "\nThe keys have been generated for host " SD_ID128_FORMAT_STR
".\n", SD_ID128_FORMAT_VAL(machine
));
1726 #ifdef HAVE_QRENCODE
1727 /* If this is not an UTF-8 system don't print any QR codes */
1728 if (is_locale_utf8()) {
1729 fputs("\nTo transfer the verification key to your phone please scan the QR code below:\n\n", stderr
);
1730 print_qr_code(stderr
, seed
, seed_size
, n
, arg_interval
, hn
, machine
);
1750 log_error("Forward-secure sealing not available.");
1755 static int verify(sd_journal
*j
) {
1762 log_show_color(true);
1764 ORDERED_HASHMAP_FOREACH(f
, j
->files
, i
) {
1766 usec_t first
= 0, validated
= 0, last
= 0;
1769 if (!arg_verify_key
&& JOURNAL_HEADER_SEALED(f
->header
))
1770 log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f
->path
);
1773 k
= journal_file_verify(f
, arg_verify_key
, &first
, &validated
, &last
, true);
1775 /* If the key was invalid give up right-away. */
1778 log_warning_errno(k
, "FAIL: %s (%m)", f
->path
);
1781 char a
[FORMAT_TIMESTAMP_MAX
], b
[FORMAT_TIMESTAMP_MAX
], c
[FORMAT_TIMESPAN_MAX
];
1782 log_info("PASS: %s", f
->path
);
1784 if (arg_verify_key
&& JOURNAL_HEADER_SEALED(f
->header
)) {
1785 if (validated
> 0) {
1786 log_info("=> Validated from %s to %s, final %s entries not sealed.",
1787 format_timestamp_maybe_utc(a
, sizeof(a
), first
),
1788 format_timestamp_maybe_utc(b
, sizeof(b
), validated
),
1789 format_timespan(c
, sizeof(c
), last
> validated
? last
- validated
: 0, 0));
1790 } else if (last
> 0)
1791 log_info("=> No sealing yet, %s of entries not sealed.",
1792 format_timespan(c
, sizeof(c
), last
- first
, 0));
1794 log_info("=> No sealing yet, no entries in file.");
1802 static int access_check_var_log_journal(sd_journal
*j
) {
1804 _cleanup_strv_free_
char **g
= NULL
;
1814 /* If we are root, we should have access, don't warn. */
1818 /* If we are in the 'systemd-journal' group, we should have
1820 r
= in_group("systemd-journal");
1822 return log_error_errno(r
, "Failed to check if we are in the 'systemd-journal' group: %m");
1827 if (laccess("/run/log/journal", F_OK
) >= 0)
1828 dir
= "/run/log/journal";
1830 dir
= "/var/log/journal";
1832 /* If we are in any of the groups listed in the journal ACLs,
1833 * then all is good, too. Let's enumerate all groups from the
1834 * default ACL of the directory, which generally should allow
1835 * access to most journal files too. */
1836 r
= acl_search_groups(dir
, &g
);
1838 return log_error_errno(r
, "Failed to search journal ACL: %m");
1842 /* Print a pretty list, if there were ACLs set. */
1843 if (!strv_isempty(g
)) {
1844 _cleanup_free_
char *s
= NULL
;
1846 /* Thre are groups in the ACL, let's list them */
1847 r
= strv_extend(&g
, "systemd-journal");
1854 s
= strv_join(g
, "', '");
1858 log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
1859 " Users in groups '%s' can see all messages.\n"
1860 " Pass -q to turn off this notice.", s
);
1865 /* If no ACLs were found, print a short version of the message. */
1866 log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
1867 " Users in the 'systemd-journal' group can see all messages. Pass -q to\n"
1868 " turn off this notice.");
1873 static int access_check(sd_journal
*j
) {
1881 if (hashmap_isempty(j
->errors
)) {
1882 if (ordered_hashmap_isempty(j
->files
))
1883 log_notice("No journal files were found.");
1888 if (hashmap_contains(j
->errors
, INT_TO_PTR(-EACCES
))) {
1889 (void) access_check_var_log_journal(j
);
1891 if (ordered_hashmap_isempty(j
->files
))
1892 r
= log_error_errno(EACCES
, "No journal files were opened due to insufficient permissions.");
1895 HASHMAP_FOREACH_KEY(path
, code
, j
->errors
, it
) {
1898 err
= abs(PTR_TO_INT(code
));
1905 log_warning_errno(err
, "Journal file %s is truncated, ignoring file.", path
);
1908 case EPROTONOSUPPORT
:
1909 log_warning_errno(err
, "Journal file %s uses an unsupported feature, ignoring file.", path
);
1913 log_warning_errno(err
, "Journal file %s corrupted, ignoring file.", path
);
1917 log_warning_errno(err
, "An error was encountered while opening journal file or directory %s, ignoring file: %m", path
);
1925 static int flush_to_var(void) {
1926 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1927 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*bus
= NULL
;
1928 _cleanup_close_
int watch_fd
= -1;
1932 log_error("--flush is not supported in conjunction with --machine=.");
1937 if (access("/run/systemd/journal/flushed", F_OK
) >= 0)
1940 /* OK, let's actually do the full logic, send SIGUSR1 to the
1941 * daemon and set up inotify to wait for the flushed file to appear */
1942 r
= bus_connect_system_systemd(&bus
);
1944 return log_error_errno(r
, "Failed to get D-Bus connection: %m");
1946 r
= sd_bus_call_method(
1948 "org.freedesktop.systemd1",
1949 "/org/freedesktop/systemd1",
1950 "org.freedesktop.systemd1.Manager",
1954 "ssi", "systemd-journald.service", "main", SIGUSR1
);
1956 return log_error_errno(r
, "Failed to kill journal service: %s", bus_error_message(&error
, r
));
1958 mkdir_p("/run/systemd/journal", 0755);
1960 watch_fd
= inotify_init1(IN_NONBLOCK
|IN_CLOEXEC
);
1962 return log_error_errno(errno
, "Failed to create inotify watch: %m");
1964 r
= inotify_add_watch(watch_fd
, "/run/systemd/journal", IN_CREATE
|IN_DONT_FOLLOW
|IN_ONLYDIR
);
1966 return log_error_errno(errno
, "Failed to watch journal directory: %m");
1969 if (access("/run/systemd/journal/flushed", F_OK
) >= 0)
1972 if (errno
!= ENOENT
)
1973 return log_error_errno(errno
, "Failed to check for existence of /run/systemd/journal/flushed: %m");
1975 r
= fd_wait_for_event(watch_fd
, POLLIN
, USEC_INFINITY
);
1977 return log_error_errno(r
, "Failed to wait for event: %m");
1979 r
= flush_fd(watch_fd
);
1981 return log_error_errno(r
, "Failed to flush inotify events: %m");
1987 static int send_signal_and_wait(int sig
, const char *watch_path
) {
1988 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*bus
= NULL
;
1989 _cleanup_close_
int watch_fd
= -1;
1994 log_error("--sync and --rotate are not supported in conjunction with --machine=.");
1998 start
= now(CLOCK_MONOTONIC
);
2000 /* This call sends the specified signal to journald, and waits
2001 * for acknowledgment by watching the mtime of the specified
2002 * flag file. This is used to trigger syncing or rotation and
2003 * then wait for the operation to complete. */
2008 /* See if a sync happened by now. */
2009 r
= read_timestamp_file(watch_path
, &tstamp
);
2010 if (r
< 0 && r
!= -ENOENT
)
2011 return log_error_errno(errno
, "Failed to read %s: %m", watch_path
);
2012 if (r
>= 0 && tstamp
>= start
)
2015 /* Let's ask for a sync, but only once. */
2017 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2019 r
= bus_connect_system_systemd(&bus
);
2021 return log_error_errno(r
, "Failed to get D-Bus connection: %m");
2023 r
= sd_bus_call_method(
2025 "org.freedesktop.systemd1",
2026 "/org/freedesktop/systemd1",
2027 "org.freedesktop.systemd1.Manager",
2031 "ssi", "systemd-journald.service", "main", sig
);
2033 return log_error_errno(r
, "Failed to kill journal service: %s", bus_error_message(&error
, r
));
2038 /* Let's install the inotify watch, if we didn't do that yet. */
2041 mkdir_p("/run/systemd/journal", 0755);
2043 watch_fd
= inotify_init1(IN_NONBLOCK
|IN_CLOEXEC
);
2045 return log_error_errno(errno
, "Failed to create inotify watch: %m");
2047 r
= inotify_add_watch(watch_fd
, "/run/systemd/journal", IN_MOVED_TO
|IN_DONT_FOLLOW
|IN_ONLYDIR
);
2049 return log_error_errno(errno
, "Failed to watch journal directory: %m");
2051 /* Recheck the flag file immediately, so that we don't miss any event since the last check. */
2055 /* OK, all preparatory steps done, let's wait until
2056 * inotify reports an event. */
2058 r
= fd_wait_for_event(watch_fd
, POLLIN
, USEC_INFINITY
);
2060 return log_error_errno(r
, "Failed to wait for event: %m");
2062 r
= flush_fd(watch_fd
);
2064 return log_error_errno(r
, "Failed to flush inotify events: %m");
2070 static int rotate(void) {
2071 return send_signal_and_wait(SIGUSR2
, "/run/systemd/journal/rotated");
2074 static int sync_journal(void) {
2075 return send_signal_and_wait(SIGRTMIN
+1, "/run/systemd/journal/synced");
2078 int main(int argc
, char *argv
[]) {
2080 _cleanup_(sd_journal_closep
) sd_journal
*j
= NULL
;
2081 bool need_seek
= false;
2082 sd_id128_t previous_boot_id
;
2083 bool previous_boot_id_valid
= false, first_line
= true;
2085 bool ellipsized
= false;
2087 setlocale(LC_ALL
, "");
2088 log_parse_environment();
2091 r
= parse_argv(argc
, argv
);
2095 signal(SIGWINCH
, columns_lines_cache_reset
);
2098 /* Increase max number of open files to 16K if we can, we
2099 * might needs this when browsing journal files, which might
2100 * be split up into many files. */
2101 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
2103 switch (arg_action
) {
2105 case ACTION_NEW_ID128
:
2106 r
= generate_new_id128();
2109 case ACTION_SETUP_KEYS
:
2113 case ACTION_LIST_CATALOG
:
2114 case ACTION_DUMP_CATALOG
:
2115 case ACTION_UPDATE_CATALOG
: {
2116 _cleanup_free_
char *database
;
2118 database
= path_join(arg_root
, CATALOG_DATABASE
, NULL
);
2124 if (arg_action
== ACTION_UPDATE_CATALOG
) {
2125 r
= catalog_update(database
, arg_root
, catalog_file_dirs
);
2127 log_error_errno(r
, "Failed to list catalog: %m");
2129 bool oneline
= arg_action
== ACTION_LIST_CATALOG
;
2131 pager_open(arg_no_pager
, arg_pager_end
);
2134 r
= catalog_list_items(stdout
, database
, oneline
, argv
+ optind
);
2136 r
= catalog_list(stdout
, database
, oneline
);
2138 log_error_errno(r
, "Failed to list catalog: %m");
2157 case ACTION_PRINT_HEADER
:
2159 case ACTION_DISK_USAGE
:
2160 case ACTION_LIST_BOOTS
:
2162 case ACTION_LIST_FIELDS
:
2163 case ACTION_LIST_FIELD_NAMES
:
2164 /* These ones require access to the journal files, continue below. */
2168 assert_not_reached("Unknown action");
2172 r
= sd_journal_open_directory(&j
, arg_directory
, arg_journal_type
);
2174 r
= sd_journal_open_directory(&j
, arg_root
, arg_journal_type
| SD_JOURNAL_OS_ROOT
);
2175 else if (arg_file_stdin
) {
2176 int ifd
= STDIN_FILENO
;
2177 r
= sd_journal_open_files_fd(&j
, &ifd
, 1, 0);
2178 } else if (arg_file
)
2179 r
= sd_journal_open_files(&j
, (const char**) arg_file
, 0);
2180 else if (arg_machine
) {
2181 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2182 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2183 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*bus
= NULL
;
2186 if (geteuid() != 0) {
2187 /* The file descriptor returned by OpenMachineRootDirectory() will be owned by users/groups of
2188 * the container, thus we need root privileges to override them. */
2189 log_error("Using the --machine= switch requires root privileges.");
2194 r
= sd_bus_open_system(&bus
);
2196 log_error_errno(r
, "Failed to open system bus: %m");
2200 r
= sd_bus_call_method(
2202 "org.freedesktop.machine1",
2203 "/org/freedesktop/machine1",
2204 "org.freedesktop.machine1.Manager",
2205 "OpenMachineRootDirectory",
2210 log_error_errno(r
, "Failed to open root directory: %s", bus_error_message(&error
, r
));
2214 r
= sd_bus_message_read(reply
, "h", &fd
);
2216 bus_log_parse_error(r
);
2220 fd
= fcntl(fd
, F_DUPFD_CLOEXEC
, 3);
2222 r
= log_error_errno(errno
, "Failed to duplicate file descriptor: %m");
2226 r
= sd_journal_open_directory_fd(&j
, fd
, SD_JOURNAL_OS_ROOT
);
2230 r
= sd_journal_open(&j
, !arg_merge
*SD_JOURNAL_LOCAL_ONLY
+ arg_journal_type
);
2232 log_error_errno(r
, "Failed to open %s: %m", arg_directory
?: arg_file
? "files" : "journal");
2236 r
= access_check(j
);
2240 switch (arg_action
) {
2242 case ACTION_NEW_ID128
:
2243 case ACTION_SETUP_KEYS
:
2244 case ACTION_LIST_CATALOG
:
2245 case ACTION_DUMP_CATALOG
:
2246 case ACTION_UPDATE_CATALOG
:
2250 assert_not_reached("Unexpected action.");
2252 case ACTION_PRINT_HEADER
:
2253 journal_print_header(j
);
2261 case ACTION_DISK_USAGE
: {
2263 char sbytes
[FORMAT_BYTES_MAX
];
2265 r
= sd_journal_get_usage(j
, &bytes
);
2269 printf("Archived and active journals take up %s in the file system.\n",
2270 format_bytes(sbytes
, sizeof(sbytes
), bytes
));
2274 case ACTION_LIST_BOOTS
:
2278 case ACTION_VACUUM
: {
2282 HASHMAP_FOREACH(d
, j
->directories_by_path
, i
) {
2288 q
= journal_directory_vacuum(d
->path
, arg_vacuum_size
, arg_vacuum_n_files
, arg_vacuum_time
, NULL
, true);
2290 log_error_errno(q
, "Failed to vacuum %s: %m", d
->path
);
2298 case ACTION_LIST_FIELD_NAMES
: {
2301 SD_JOURNAL_FOREACH_FIELD(j
, field
) {
2302 printf("%s\n", field
);
2311 case ACTION_LIST_FIELDS
:
2315 assert_not_reached("Unknown action");
2318 if (arg_boot_offset
!= 0 &&
2319 sd_journal_has_runtime_files(j
) > 0 &&
2320 sd_journal_has_persistent_files(j
) == 0) {
2321 log_info("Specifying boot ID has no effect, no persistent journal was found");
2325 /* add_boot() must be called first!
2326 * It may need to seek the journal to find parent boot IDs. */
2337 log_error_errno(r
, "Failed to add filter for units: %m");
2341 r
= add_syslog_identifier(j
);
2343 log_error_errno(r
, "Failed to add filter for syslog identifiers: %m");
2347 r
= add_priorities(j
);
2351 r
= add_matches(j
, argv
+ optind
);
2355 if (_unlikely_(log_get_max_level() >= LOG_DEBUG
)) {
2356 _cleanup_free_
char *filter
;
2358 filter
= journal_make_match_string(j
);
2362 log_debug("Journal filter: %s", filter
);
2365 if (arg_action
== ACTION_LIST_FIELDS
) {
2371 r
= sd_journal_set_data_threshold(j
, 0);
2373 log_error_errno(r
, "Failed to unset data size threshold: %m");
2377 r
= sd_journal_query_unique(j
, arg_field
);
2379 log_error_errno(r
, "Failed to query unique data objects: %m");
2383 SD_JOURNAL_FOREACH_UNIQUE(j
, data
, size
) {
2386 if (arg_lines
>= 0 && n_shown
>= arg_lines
)
2389 eq
= memchr(data
, '=', size
);
2391 printf("%.*s\n", (int) (size
- ((const uint8_t*) eq
- (const uint8_t*) data
+ 1)), (const char*) eq
+ 1);
2393 printf("%.*s\n", (int) size
, (const char*) data
);
2402 /* Opening the fd now means the first sd_journal_wait() will actually wait */
2404 r
= sd_journal_get_fd(j
);
2405 if (r
== -EMEDIUMTYPE
) {
2406 log_error_errno(r
, "The --follow switch is not supported in conjunction with reading from STDIN.");
2410 log_error_errno(r
, "Failed to get journal fd: %m");
2415 if (arg_cursor
|| arg_after_cursor
) {
2416 r
= sd_journal_seek_cursor(j
, arg_cursor
?: arg_after_cursor
);
2418 log_error_errno(r
, "Failed to seek to cursor: %m");
2423 r
= sd_journal_next_skip(j
, 1 + !!arg_after_cursor
);
2425 r
= sd_journal_previous_skip(j
, 1 + !!arg_after_cursor
);
2427 if (arg_after_cursor
&& r
< 2) {
2428 /* We couldn't find the next entry after the cursor. */
2435 } else if (arg_since_set
&& !arg_reverse
) {
2436 r
= sd_journal_seek_realtime_usec(j
, arg_since
);
2438 log_error_errno(r
, "Failed to seek to date: %m");
2441 r
= sd_journal_next(j
);
2443 } else if (arg_until_set
&& arg_reverse
) {
2444 r
= sd_journal_seek_realtime_usec(j
, arg_until
);
2446 log_error_errno(r
, "Failed to seek to date: %m");
2449 r
= sd_journal_previous(j
);
2451 } else if (arg_lines
>= 0) {
2452 r
= sd_journal_seek_tail(j
);
2454 log_error_errno(r
, "Failed to seek to tail: %m");
2458 r
= sd_journal_previous_skip(j
, arg_lines
);
2460 } else if (arg_reverse
) {
2461 r
= sd_journal_seek_tail(j
);
2463 log_error_errno(r
, "Failed to seek to tail: %m");
2467 r
= sd_journal_previous(j
);
2470 r
= sd_journal_seek_head(j
);
2472 log_error_errno(r
, "Failed to seek to head: %m");
2476 r
= sd_journal_next(j
);
2480 log_error_errno(r
, "Failed to iterate through journal: %m");
2488 printf("-- No entries --\n");
2494 pager_open(arg_no_pager
, arg_pager_end
);
2498 char start_buf
[FORMAT_TIMESTAMP_MAX
], end_buf
[FORMAT_TIMESTAMP_MAX
];
2500 r
= sd_journal_get_cutoff_realtime_usec(j
, &start
, &end
);
2502 log_error_errno(r
, "Failed to get cutoff: %m");
2508 printf("-- Logs begin at %s. --\n",
2509 format_timestamp_maybe_utc(start_buf
, sizeof(start_buf
), start
));
2511 printf("-- Logs begin at %s, end at %s. --\n",
2512 format_timestamp_maybe_utc(start_buf
, sizeof(start_buf
), start
),
2513 format_timestamp_maybe_utc(end_buf
, sizeof(end_buf
), end
));
2518 while (arg_lines
< 0 || n_shown
< arg_lines
|| (arg_follow
&& !first_line
)) {
2523 r
= sd_journal_next(j
);
2525 r
= sd_journal_previous(j
);
2527 log_error_errno(r
, "Failed to iterate through journal: %m");
2534 if (arg_until_set
&& !arg_reverse
) {
2537 r
= sd_journal_get_realtime_usec(j
, &usec
);
2539 log_error_errno(r
, "Failed to determine timestamp: %m");
2542 if (usec
> arg_until
)
2546 if (arg_since_set
&& arg_reverse
) {
2549 r
= sd_journal_get_realtime_usec(j
, &usec
);
2551 log_error_errno(r
, "Failed to determine timestamp: %m");
2554 if (usec
< arg_since
)
2558 if (!arg_merge
&& !arg_quiet
) {
2561 r
= sd_journal_get_monotonic_usec(j
, NULL
, &boot_id
);
2563 if (previous_boot_id_valid
&&
2564 !sd_id128_equal(boot_id
, previous_boot_id
))
2565 printf("%s-- Reboot --%s\n",
2566 ansi_highlight(), ansi_normal());
2568 previous_boot_id
= boot_id
;
2569 previous_boot_id_valid
= true;
2574 arg_all
* OUTPUT_SHOW_ALL
|
2575 arg_full
* OUTPUT_FULL_WIDTH
|
2576 colors_enabled() * OUTPUT_COLOR
|
2577 arg_catalog
* OUTPUT_CATALOG
|
2578 arg_utc
* OUTPUT_UTC
|
2579 arg_no_hostname
* OUTPUT_NO_HOSTNAME
;
2581 r
= output_journal(stdout
, j
, arg_output
, 0, flags
, &ellipsized
);
2583 if (r
== -EADDRNOTAVAIL
)
2585 else if (r
< 0 || ferror(stdout
))
2592 if (arg_show_cursor
) {
2593 _cleanup_free_
char *cursor
= NULL
;
2595 r
= sd_journal_get_cursor(j
, &cursor
);
2596 if (r
< 0 && r
!= -EADDRNOTAVAIL
)
2597 log_error_errno(r
, "Failed to get cursor: %m");
2599 printf("-- cursor: %s\n", cursor
);
2605 r
= sd_journal_wait(j
, (uint64_t) -1);
2607 log_error_errno(r
, "Couldn't wait for journal event: %m");
2617 strv_free(arg_file
);
2619 strv_free(arg_syslog_identifier
);
2620 strv_free(arg_system_units
);
2621 strv_free(arg_user_units
);
2625 return r
< 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;