1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <unistd.h>
#include "sd-daemon.h"
#include "sd-messages.h"
#include "format-util.h"
#include "journal-authenticate.h"
#include "journald-kmsg.h"
#include "journald-server.h"
#include "journald-syslog.h"
#include "main-func.h"
#include "process-util.h"
#include "sigbus.h"
#include "terminal-util.h"
static int run(int argc, char *argv[]) {
_cleanup_(server_freep) Server *s = NULL;
const char *namespace;
LogTarget log_target;
int r;
if (argc > 2)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes one or no arguments.");
namespace = argc > 1 ? empty_to_null(argv[1]) : NULL;
log_set_facility(LOG_SYSLOG);
if (namespace)
/* If we run for a log namespace, then we ourselves can log to the main journald. */
log_setup();
else {
/* So here's the deal if we run as the main journald: we can't be considered as regular
* daemon when it comes to logging hence LOG_TARGET_AUTO won't do the right thing for
* us. Hence explicitly log to the console if we're started from a console or to kmsg
* otherwise. */
log_target = isatty(STDERR_FILENO) ? LOG_TARGET_CONSOLE : LOG_TARGET_KMSG;
log_set_prohibit_ipc(true); /* better safe than sorry */
log_set_target(log_target);
log_parse_environment();
log_open();
}
umask(0022);
sigbus_install();
r = server_new(&s);
if (r < 0)
return log_oom();
r = server_init(s, namespace);
if (r < 0)
return r;
server_vacuum(s, /* verbose = */ false);
server_flush_to_var(s, /* require_flag_file = */ true);
server_flush_dev_kmsg(s);
if (s->namespace)
log_debug("systemd-journald running as PID "PID_FMT" for namespace '%s'.", getpid_cached(), s->namespace);
else
log_debug("systemd-journald running as PID "PID_FMT" for the system.", getpid_cached());
server_driver_message(s, 0,
"MESSAGE_ID=" SD_MESSAGE_JOURNAL_START_STR,
LOG_MESSAGE("Journal started"),
NULL);
/* Make sure to send the usage message *after* flushing the
* journal so entries from the runtime journals are ordered
* before this message. See #4190 for some details. */
server_space_usage_message(s, NULL);
for (;;) {
usec_t t, n;
r = sd_event_get_state(s->event);
if (r < 0)
return log_error_errno(r, "Failed to get event loop state: %m");
if (r == SD_EVENT_FINISHED)
break;
r = sd_event_now(s->event, CLOCK_REALTIME, &n);
if (r < 0)
return log_error_errno(r, "Failed to get the current time: %m");
if (s->max_retention_usec > 0 && s->oldest_file_usec > 0) {
/* Calculate when to rotate the next time */
t = usec_sub_unsigned(usec_add(s->oldest_file_usec, s->max_retention_usec), n);
/* The retention time is reached, so let's vacuum! */
if (t <= 0) {
log_info("Retention time reached, vacuuming.");
server_vacuum(s, /* verbose = */ false);
continue;
}
} else
t = USEC_INFINITY;
#if HAVE_GCRYPT
if (s->system_journal) {
usec_t u;
if (journal_file_next_evolve_usec(s->system_journal, &u))
t = MIN(t, usec_sub_unsigned(u, n));
}
#endif
r = sd_event_run(s->event, t);
if (r < 0)
return log_error_errno(r, "Failed to run event loop: %m");
server_maybe_append_tags(s);
server_maybe_warn_forward_syslog_missed(s);
}
if (s->namespace)
log_debug("systemd-journald stopped as PID "PID_FMT" for namespace '%s'.", getpid_cached(), s->namespace);
else
log_debug("systemd-journald stopped as PID "PID_FMT" for the system.", getpid_cached());
server_driver_message(s, 0,
"MESSAGE_ID=" SD_MESSAGE_JOURNAL_STOP_STR,
LOG_MESSAGE("Journal stopped"),
NULL);
return 0;
}
DEFINE_MAIN_FUNCTION(run);
|