journald: add exit on idle
This commit is contained in:
parent
6d4d600260
commit
65c398c031
|
@ -77,6 +77,8 @@
|
||||||
|
|
||||||
#define DEFERRED_CLOSES_MAX (4096)
|
#define DEFERRED_CLOSES_MAX (4096)
|
||||||
|
|
||||||
|
#define IDLE_TIMEOUT_USEC (30*USEC_PER_SEC)
|
||||||
|
|
||||||
static int determine_path_usage(
|
static int determine_path_usage(
|
||||||
Server *s,
|
Server *s,
|
||||||
const char *path,
|
const char *path,
|
||||||
|
@ -1216,6 +1218,7 @@ finish:
|
||||||
if (k < 0)
|
if (k < 0)
|
||||||
log_warning_errno(k, "Failed to touch %s, ignoring: %m", fn);
|
log_warning_errno(k, "Failed to touch %s, ignoring: %m", fn);
|
||||||
|
|
||||||
|
server_refresh_idle_timer(s);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1244,10 +1247,16 @@ static int server_relinquish_var(Server *s) {
|
||||||
if (unlink(fn) < 0 && errno != ENOENT)
|
if (unlink(fn) < 0 && errno != ENOENT)
|
||||||
log_warning_errno(errno, "Failed to unlink %s, ignoring: %m", fn);
|
log_warning_errno(errno, "Failed to unlink %s, ignoring: %m", fn);
|
||||||
|
|
||||||
|
server_refresh_idle_timer(s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
|
int server_process_datagram(
|
||||||
|
sd_event_source *es,
|
||||||
|
int fd,
|
||||||
|
uint32_t revents,
|
||||||
|
void *userdata) {
|
||||||
|
|
||||||
Server *s = userdata;
|
Server *s = userdata;
|
||||||
struct ucred *ucred = NULL;
|
struct ucred *ucred = NULL;
|
||||||
struct timeval *tv = NULL;
|
struct timeval *tv = NULL;
|
||||||
|
@ -1362,6 +1371,8 @@ int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void
|
||||||
}
|
}
|
||||||
|
|
||||||
close_many(fds, n_fds);
|
close_many(fds, n_fds);
|
||||||
|
|
||||||
|
server_refresh_idle_timer(s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1373,6 +1384,8 @@ static void server_full_flush(Server *s) {
|
||||||
server_vacuum(s, false);
|
server_vacuum(s, false);
|
||||||
|
|
||||||
server_space_usage_message(s, NULL);
|
server_space_usage_message(s, NULL);
|
||||||
|
|
||||||
|
server_refresh_idle_timer(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
|
static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
|
||||||
|
@ -2001,6 +2014,28 @@ static int vl_method_relinquish_var(Varlink *link, JsonVariant *parameters, Varl
|
||||||
return varlink_reply(link, NULL);
|
return varlink_reply(link, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int vl_connect(VarlinkServer *server, Varlink *link, void *userdata) {
|
||||||
|
Server *s = userdata;
|
||||||
|
|
||||||
|
assert(server);
|
||||||
|
assert(link);
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
(void) server_start_or_stop_idle_timer(s); /* maybe we are no longer idle */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vl_disconnect(VarlinkServer *server, Varlink *link, void *userdata) {
|
||||||
|
Server *s = userdata;
|
||||||
|
|
||||||
|
assert(server);
|
||||||
|
assert(link);
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
(void) server_start_or_stop_idle_timer(s); /* maybe we are idle now */
|
||||||
|
}
|
||||||
|
|
||||||
static int server_open_varlink(Server *s) {
|
static int server_open_varlink(Server *s) {
|
||||||
const char *fn;
|
const char *fn;
|
||||||
int r;
|
int r;
|
||||||
|
@ -2022,6 +2057,14 @@ static int server_open_varlink(Server *s) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
r = varlink_server_bind_connect(s->varlink_server, vl_connect);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = varlink_server_bind_disconnect(s->varlink_server, vl_disconnect);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
fn = strjoina(s->runtime_directory, "/io.systemd.journal");
|
fn = strjoina(s->runtime_directory, "/io.systemd.journal");
|
||||||
|
|
||||||
r = varlink_server_listen_address(s->varlink_server, fn, 0600);
|
r = varlink_server_listen_address(s->varlink_server, fn, 0600);
|
||||||
|
@ -2035,6 +2078,93 @@ static int server_open_varlink(Server *s) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool server_is_idle(Server *s) {
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
/* The server for the main namespace is never idle */
|
||||||
|
if (!s->namespace)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* If a retention maximum is set larger than the idle time we need to be running to enforce it, hence
|
||||||
|
* turn off the idle logic. */
|
||||||
|
if (s->max_retention_usec > IDLE_TIMEOUT_USEC)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* We aren't idle if we have a varlink client */
|
||||||
|
if (varlink_server_current_connections(s->varlink_server) > 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* If we have stdout streams we aren't idle */
|
||||||
|
if (s->n_stdout_streams > 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int server_idle_handler(sd_event_source *source, uint64_t usec, void *userdata) {
|
||||||
|
Server *s = userdata;
|
||||||
|
|
||||||
|
assert(source);
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
log_debug("Server is idle, exiting.");
|
||||||
|
sd_event_exit(s->event, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int server_start_or_stop_idle_timer(Server *s) {
|
||||||
|
_cleanup_(sd_event_source_unrefp) sd_event_source *source = NULL;
|
||||||
|
usec_t when;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
if (!server_is_idle(s)) {
|
||||||
|
s->idle_event_source = sd_event_source_disable_unref(s->idle_event_source);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->idle_event_source)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
r = sd_event_now(s->event, CLOCK_MONOTONIC, &when);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to determine current time: %m");
|
||||||
|
|
||||||
|
r = sd_event_add_time(s->event, &source, CLOCK_MONOTONIC, usec_add(when, IDLE_TIMEOUT_USEC), 0, server_idle_handler, s);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to allocate idle timer: %m");
|
||||||
|
|
||||||
|
r = sd_event_source_set_priority(source, SD_EVENT_PRIORITY_IDLE);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to set idle timer priority: %m");
|
||||||
|
|
||||||
|
(void) sd_event_source_set_description(source, "idle-timer");
|
||||||
|
|
||||||
|
s->idle_event_source = TAKE_PTR(source);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int server_refresh_idle_timer(Server *s) {
|
||||||
|
usec_t when;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
if (!s->idle_event_source)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = sd_event_now(s->event, CLOCK_MONOTONIC, &when);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to determine current time: %m");
|
||||||
|
|
||||||
|
r = sd_event_source_set_time(s->idle_event_source, usec_add(when, IDLE_TIMEOUT_USEC));
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to refresh idle timer: %m");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int set_namespace(Server *s, const char *namespace) {
|
static int set_namespace(Server *s, const char *namespace) {
|
||||||
assert(s);
|
assert(s);
|
||||||
|
|
||||||
|
@ -2298,7 +2428,12 @@ int server_init(Server *s, const char *namespace) {
|
||||||
|
|
||||||
(void) client_context_acquire_default(s);
|
(void) client_context_acquire_default(s);
|
||||||
|
|
||||||
return system_journal_open(s, false, false);
|
r = system_journal_open(s, false, false);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
server_start_or_stop_idle_timer(s);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void server_maybe_append_tags(Server *s) {
|
void server_maybe_append_tags(Server *s) {
|
||||||
|
@ -2351,6 +2486,7 @@ void server_done(Server *s) {
|
||||||
sd_event_source_unref(s->hostname_event_source);
|
sd_event_source_unref(s->hostname_event_source);
|
||||||
sd_event_source_unref(s->notify_event_source);
|
sd_event_source_unref(s->notify_event_source);
|
||||||
sd_event_source_unref(s->watchdog_event_source);
|
sd_event_source_unref(s->watchdog_event_source);
|
||||||
|
sd_event_source_unref(s->idle_event_source);
|
||||||
sd_event_unref(s->event);
|
sd_event_unref(s->event);
|
||||||
|
|
||||||
safe_close(s->syslog_fd);
|
safe_close(s->syslog_fd);
|
||||||
|
|
|
@ -86,6 +86,7 @@ struct Server {
|
||||||
sd_event_source *hostname_event_source;
|
sd_event_source *hostname_event_source;
|
||||||
sd_event_source *notify_event_source;
|
sd_event_source *notify_event_source;
|
||||||
sd_event_source *watchdog_event_source;
|
sd_event_source *watchdog_event_source;
|
||||||
|
sd_event_source *idle_event_source;
|
||||||
|
|
||||||
JournalFile *runtime_journal;
|
JournalFile *runtime_journal;
|
||||||
JournalFile *system_journal;
|
JournalFile *system_journal;
|
||||||
|
@ -218,3 +219,6 @@ int server_flush_to_var(Server *s, bool require_flag_file);
|
||||||
void server_maybe_append_tags(Server *s);
|
void server_maybe_append_tags(Server *s);
|
||||||
int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void *userdata);
|
int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void *userdata);
|
||||||
void server_space_usage_message(Server *s, JournalStorage *storage);
|
void server_space_usage_message(Server *s, JournalStorage *storage);
|
||||||
|
|
||||||
|
int server_start_or_stop_idle_timer(Server *s);
|
||||||
|
int server_refresh_idle_timer(Server *s);
|
||||||
|
|
|
@ -110,6 +110,8 @@ void stdout_stream_free(StdoutStream *s) {
|
||||||
|
|
||||||
if (s->in_notify_queue)
|
if (s->in_notify_queue)
|
||||||
LIST_REMOVE(stdout_stream_notify_queue, s->server->stdout_streams_notify_queue, s);
|
LIST_REMOVE(stdout_stream_notify_queue, s->server->stdout_streams_notify_queue, s);
|
||||||
|
|
||||||
|
(void) server_start_or_stop_idle_timer(s->server); /* Maybe we are idle now? */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->event_source) {
|
if (s->event_source) {
|
||||||
|
@ -631,6 +633,8 @@ int stdout_stream_install(Server *s, int fd, StdoutStream **ret) {
|
||||||
LIST_PREPEND(stdout_stream, s->stdout_streams, stream);
|
LIST_PREPEND(stdout_stream, s->stdout_streams, stream);
|
||||||
s->n_stdout_streams++;
|
s->n_stdout_streams++;
|
||||||
|
|
||||||
|
(void) server_start_or_stop_idle_timer(s); /* Maybe no longer idle? */
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
*ret = stream;
|
*ret = stream;
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,6 @@ LogsDirectory=journal/%m.%i
|
||||||
LogsDirectoryMode=02755
|
LogsDirectoryMode=02755
|
||||||
MemoryDenyWriteExecute=yes
|
MemoryDenyWriteExecute=yes
|
||||||
NoNewPrivileges=yes
|
NoNewPrivileges=yes
|
||||||
Restart=always
|
|
||||||
RestartSec=0
|
|
||||||
RestrictAddressFamilies=AF_UNIX AF_NETLINK
|
RestrictAddressFamilies=AF_UNIX AF_NETLINK
|
||||||
RestrictNamespaces=yes
|
RestrictNamespaces=yes
|
||||||
RestrictRealtime=yes
|
RestrictRealtime=yes
|
||||||
|
|
Loading…
Reference in New Issue