]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/journal/journalctl-misc.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "dirent-util.h"
5 #include "format-table.h"
6 #include "format-util.h"
7 #include "journal-internal.h"
8 #include "journal-verify.h"
9 #include "journalctl.h"
10 #include "journalctl-misc.h"
11 #include "journalctl-util.h"
12 #include "logs-show.h"
13 #include "syslog-util.h"
15 int action_print_header(void) {
16 _cleanup_(sd_journal_closep
) sd_journal
*j
= NULL
;
19 assert(arg_action
== ACTION_PRINT_HEADER
);
21 r
= acquire_journal(&j
);
25 journal_print_header(j
);
29 int action_verify(void) {
30 _cleanup_(sd_journal_closep
) sd_journal
*j
= NULL
;
33 assert(arg_action
== ACTION_VERIFY
);
35 r
= acquire_journal(&j
);
42 ORDERED_HASHMAP_FOREACH(f
, j
->files
) {
44 usec_t first
= 0, validated
= 0, last
= 0;
47 if (!arg_verify_key
&& JOURNAL_HEADER_SEALED(f
->header
))
48 log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f
->path
);
51 k
= journal_file_verify(f
, arg_verify_key
, &first
, &validated
, &last
, /* show_progress = */ !arg_quiet
);
53 /* If the key was invalid give up right-away. */
56 r
= log_warning_errno(k
, "FAIL: %s (%m)", f
->path
);
58 char a
[FORMAT_TIMESTAMP_MAX
], b
[FORMAT_TIMESTAMP_MAX
];
59 log_full(arg_quiet
? LOG_DEBUG
: LOG_INFO
, "PASS: %s", f
->path
);
61 if (arg_verify_key
&& JOURNAL_HEADER_SEALED(f
->header
)) {
63 log_full(arg_quiet
? LOG_DEBUG
: LOG_INFO
,
64 "=> Validated from %s to %s, final %s entries not sealed.",
65 format_timestamp_maybe_utc(a
, sizeof(a
), first
),
66 format_timestamp_maybe_utc(b
, sizeof(b
), validated
),
67 FORMAT_TIMESPAN(last
> validated
? last
- validated
: 0, 0));
69 log_full(arg_quiet
? LOG_DEBUG
: LOG_INFO
,
70 "=> No sealing yet, %s of entries not sealed.",
71 FORMAT_TIMESPAN(last
- first
, 0));
73 log_full(arg_quiet
? LOG_DEBUG
: LOG_INFO
,
74 "=> No sealing yet, no entries in file.");
82 int action_disk_usage(void) {
83 _cleanup_(sd_journal_closep
) sd_journal
*j
= NULL
;
87 assert(arg_action
== ACTION_DISK_USAGE
);
89 r
= acquire_journal(&j
);
93 r
= sd_journal_get_usage(j
, &bytes
);
95 return log_error_errno(r
, "Failed to get disk usage: %m");
97 printf("Archived and active journals take up %s in the file system.\n", FORMAT_BYTES(bytes
));
101 int action_list_boots(void) {
102 _cleanup_(sd_journal_closep
) sd_journal
*j
= NULL
;
103 _cleanup_(table_unrefp
) Table
*table
= NULL
;
104 _cleanup_free_ BootId
*boots
= NULL
;
108 assert(arg_action
== ACTION_LIST_BOOTS
);
110 r
= acquire_journal(&j
);
114 r
= journal_get_boots(j
, &boots
, &n_boots
);
116 return log_error_errno(r
, "Failed to determine boots: %m");
120 table
= table_new("idx", "boot id", "first entry", "last entry");
125 table_set_width(table
, 0);
127 r
= table_set_json_field_name(table
, 0, "index");
129 return log_error_errno(r
, "Failed to set JSON field name of column 0: %m");
131 (void) table_set_sort(table
, (size_t) 0);
132 (void) table_set_reverse(table
, 0, arg_reverse
);
134 FOREACH_ARRAY(i
, boots
, n_boots
) {
135 r
= table_add_many(table
,
136 TABLE_INT
, (int)(i
- boots
) - (int) n_boots
+ 1,
137 TABLE_SET_ALIGN_PERCENT
, 100,
139 TABLE_TIMESTAMP
, i
->first_usec
,
140 TABLE_TIMESTAMP
, i
->last_usec
);
142 return table_log_add_error(r
);
145 r
= table_print_with_pager(table
, arg_json_format_flags
, arg_pager_flags
, !arg_quiet
);
147 return table_log_print_error(r
);
152 int action_list_fields(void) {
153 _cleanup_(sd_journal_closep
) sd_journal
*j
= NULL
;
156 assert(arg_action
== ACTION_LIST_FIELDS
);
159 r
= acquire_journal(&j
);
163 if (!journal_boot_has_effect(j
))
166 r
= sd_journal_set_data_threshold(j
, 0);
168 return log_error_errno(r
, "Failed to unset data size threshold: %m");
170 r
= sd_journal_query_unique(j
, arg_field
);
172 return log_error_errno(r
, "Failed to query unique data objects: %m");
176 SD_JOURNAL_FOREACH_UNIQUE(j
, data
, size
) {
179 if (arg_lines
>= 0 && n_shown
>= arg_lines
)
182 eq
= memchr(data
, '=', size
);
184 printf("%.*s\n", (int) (size
- ((const uint8_t*) eq
- (const uint8_t*) data
+ 1)), (const char*) eq
+ 1);
186 printf("%.*s\n", (int) size
, (const char*) data
);
194 int action_list_field_names(void) {
195 _cleanup_(sd_journal_closep
) sd_journal
*j
= NULL
;
198 assert(arg_action
== ACTION_LIST_FIELD_NAMES
);
200 r
= acquire_journal(&j
);
205 SD_JOURNAL_FOREACH_FIELD(j
, field
)
206 printf("%s\n", field
);
211 int action_list_namespaces(void) {
212 _cleanup_(table_unrefp
) Table
*table
= NULL
;
214 char machine_id
[SD_ID128_STRING_MAX
];
217 assert(arg_action
== ACTION_LIST_NAMESPACES
);
219 r
= sd_id128_get_machine(&machine
);
221 return log_error_errno(r
, "Failed to get machine ID: %m");
223 sd_id128_to_string(machine
, machine_id
);
225 table
= table_new("namespace");
229 (void) table_set_sort(table
, (size_t) 0);
231 FOREACH_STRING(dir
, "/var/log/journal", "/run/log/journal") {
232 _cleanup_free_
char *path
= NULL
;
233 _cleanup_closedir_
DIR *dirp
= NULL
;
235 path
= path_join(arg_root
, dir
);
239 dirp
= opendir(path
);
241 log_debug_errno(errno
, "Failed to open directory %s, ignoring: %m", path
);
245 FOREACH_DIRENT(de
, dirp
, return log_error_errno(errno
, "Failed to iterate through %s: %m", path
)) {
248 if (!startswith(de
->d_name
, machine_id
))
251 dot
= strchr(de
->d_name
, '.');
255 if (!log_namespace_name_valid(dot
+ 1))
258 r
= table_add_cell(table
, NULL
, TABLE_STRING
, dot
+ 1);
260 return table_log_add_error(r
);
264 r
= table_print_with_pager(table
, arg_json_format_flags
, arg_pager_flags
, !arg_quiet
);
266 return table_log_print_error(r
);