#include "exit-status.h"
#include "fd-util.h"
#include "fileio.h"
-#include "fs-util.h"
#include "generator-setup.h"
#include "hashmap.h"
+#include "inotify-util.h"
#include "install.h"
#include "io-util.h"
#include "label.h"
#include "manager-dump.h"
#include "manager-serialize.h"
#include "memory-util.h"
-#include "mkdir.h"
+#include "mkdir-label.h"
#include "parse-util.h"
#include "path-lookup.h"
#include "path-util.h"
r = manager_setup_sigchld_event_source(m);
if (r < 0)
return r;
+
+#if HAVE_LIBBPF
+ if (MANAGER_IS_SYSTEM(m) && lsm_bpf_supported()) {
+ r = lsm_bpf_setup(m);
+ if (r < 0)
+ return r;
+ }
+#endif
}
if (test_run_flags == 0) {
m->prefix[dt] = mfree(m->prefix[dt]);
free(m->received_credentials);
+#if BPF_FRAMEWORK
+ lsm_bpf_destroy(m->restrict_fs);
+#endif
+
return mfree(m);
}
/* Let's finally catch up with any changes that took place while we were reloading/reexecing */
manager_catchup(m);
+ /* Create a file which will indicate when the manager started loading units the last time. */
+ (void) touch_file("/run/systemd/systemd-units-load", false,
+ m->timestamps[MANAGER_TIMESTAMP_UNITS_LOAD].realtime ?: now(CLOCK_REALTIME),
+ UID_INVALID, GID_INVALID, 0444);
+
m->honor_device_enumeration = true;
}
Manager* manager_reloading_start(Manager *m) {
m->n_reloading++;
+ dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_UNITS_LOAD);
return m;
}
+
void manager_reloading_stopp(Manager **m) {
if (*m) {
assert((*m)->n_reloading > 0);
{
/* This block is (optionally) done with the reloading counter bumped */
- _cleanup_(manager_reloading_stopp) Manager *reloading = NULL;
+ _unused_ _cleanup_(manager_reloading_stopp) Manager *reloading = NULL;
/* If we will deserialize make sure that during enumeration this is already known, so we increase the
* counter here already */
r = manager_varlink_init(m);
if (r < 0)
- log_warning_errno(r, "Failed to set up Varlink server, ignoring: %m");
+ log_warning_errno(r, "Failed to set up Varlink, ignoring: %m");
/* Third, fire things up! */
manager_coldplug(m);
return 1;
}
+void manager_trigger_run_queue(Manager *m) {
+ int r;
+
+ assert(m);
+
+ r = sd_event_source_set_enabled(
+ m->run_queue_event_source,
+ prioq_isempty(m->run_queue) ? SD_EVENT_OFF : SD_EVENT_ONESHOT);
+ if (r < 0)
+ log_warning_errno(r, "Failed to enable job run queue event source, ignoring: %m");
+}
+
static unsigned manager_dispatch_dbus_queue(Manager *m) {
unsigned n = 0, budget;
Unit *u;
}
n = recvmsg_safe(m->notify_fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC|MSG_TRUNC);
- if (IN_SET(n, -EAGAIN, -EINTR))
- return 0; /* Spurious wakeup, try again */
- if (n == -EXFULL) {
- log_warning("Got message with truncated control data (too many fds sent?), ignoring.");
- return 0;
- }
- if (n < 0)
+ if (n < 0) {
+ if (ERRNO_IS_TRANSIENT(n))
+ return 0; /* Spurious wakeup, try again */
+ if (n == -EXFULL) {
+ log_warning("Got message with truncated control data (too many fds sent?), ignoring.");
+ return 0;
+ }
/* If this is any other, real error, then let's stop processing this socket. This of course
* means we won't take notification messages anymore, but that's still better than busy
* looping around this: being woken up over and over again but being unable to actually read
* the message off the socket. */
return log_error_errno(n, "Failed to receive notification message: %m");
+ }
CMSG_FOREACH(cmsg, &msghdr) {
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
}
n = read(m->signal_fd, &sfsi, sizeof(sfsi));
- if (n != sizeof(sfsi)) {
- if (n >= 0) {
- log_warning("Truncated read from signal fd (%zu bytes), ignoring!", n);
- return 0;
- }
-
- if (IN_SET(errno, EINTR, EAGAIN))
+ if (n < 0) {
+ if (ERRNO_IS_TRANSIENT(errno))
return 0;
/* We return an error here, which will kill this handler,
* to avoid a busy loop on read error. */
return log_error_errno(errno, "Reading from signal fd failed: %m");
}
+ if (n != sizeof(sfsi)) {
+ log_warning("Truncated read from signal fd (%zu bytes), ignoring!", n);
+ return 0;
+ }
log_received_signal(sfsi.ssi_signo == SIGCHLD ||
(sfsi.ssi_signo == SIGTERM && MANAGER_IS_USER(m))
return log_error_errno(r, "Failed to enable SIGCHLD event source: %m");
while (m->objective == MANAGER_OK) {
- usec_t wait_usec, watchdog_usec;
- watchdog_usec = manager_get_watchdog(m, WATCHDOG_RUNTIME);
- if (m->runtime_watchdog_running)
- (void) watchdog_ping();
- else if (timestamp_is_set(watchdog_usec))
- manager_retry_runtime_watchdog(m);
+ (void) watchdog_ping();
if (!ratelimit_below(&rl)) {
/* Yay, something is going seriously wrong, pause a little */
continue;
/* Sleep for watchdog runtime wait time */
- if (timestamp_is_set(watchdog_usec))
- wait_usec = watchdog_runtime_wait();
- else
- wait_usec = USEC_INFINITY;
-
- r = sd_event_run(m->event, wait_usec);
+ r = sd_event_run(m->event, watchdog_runtime_wait());
if (r < 0)
return log_error_errno(r, "Failed to run event loop: %m");
}
}
void manager_set_watchdog(Manager *m, WatchdogType t, usec_t timeout) {
- int r = 0;
assert(m);
return;
if (t == WATCHDOG_RUNTIME)
- if (!timestamp_is_set(m->watchdog_overridden[WATCHDOG_RUNTIME])) {
- if (timestamp_is_set(timeout)) {
- r = watchdog_set_timeout(&timeout);
-
- if (r >= 0)
- m->runtime_watchdog_running = true;
- } else {
- watchdog_close(true);
- m->runtime_watchdog_running = false;
- }
- }
+ if (!timestamp_is_set(m->watchdog_overridden[WATCHDOG_RUNTIME]))
+ (void) watchdog_setup(timeout);
m->watchdog[t] = timeout;
}
int manager_override_watchdog(Manager *m, WatchdogType t, usec_t timeout) {
- int r = 0;
assert(m);
return 0;
if (t == WATCHDOG_RUNTIME) {
- usec_t *p;
+ usec_t usec = timestamp_is_set(timeout) ? timeout : m->watchdog[t];
- p = timestamp_is_set(timeout) ? &timeout : &m->watchdog[t];
- if (timestamp_is_set(*p)) {
- r = watchdog_set_timeout(p);
-
- if (r >= 0)
- m->runtime_watchdog_running = true;
- } else {
- watchdog_close(true);
- m->runtime_watchdog_running = false;
- }
+ (void) watchdog_setup(usec);
}
m->watchdog_overridden[t] = timeout;
-
return 0;
}
-void manager_retry_runtime_watchdog(Manager *m) {
- int r = 0;
-
- assert(m);
-
- if (timestamp_is_set(m->watchdog_overridden[WATCHDOG_RUNTIME]))
- r = watchdog_set_timeout(&m->watchdog_overridden[WATCHDOG_RUNTIME]);
- else
- r = watchdog_set_timeout(&m->watchdog[WATCHDOG_RUNTIME]);
-
- if (r >= 0)
- m->runtime_watchdog_running = true;
-}
-
int manager_reload(Manager *m) {
- _cleanup_(manager_reloading_stopp) Manager *reloading = NULL;
+ _unused_ _cleanup_(manager_reloading_stopp) Manager *reloading = NULL;
_cleanup_fdset_free_ FDSet *fds = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
}
static void user_manager_send_ready(Manager *m) {
+ int r;
+
assert(m);
/* We send READY=1 on reaching basic.target only when running in --user mode. */
if (!MANAGER_IS_USER(m) || m->ready_sent)
return;
- sd_notifyf(false,
- "READY=1\n"
- "STATUS=Reached " SPECIAL_BASIC_TARGET ".");
+ r = sd_notify(false,
+ "READY=1\n"
+ "STATUS=Reached " SPECIAL_BASIC_TARGET ".");
+ if (r < 0)
+ log_warning_errno(r, "Failed to send readiness notification, ignoring: %m");
+
m->ready_sent = true;
m->status_ready = false;
}
static void manager_send_ready(Manager *m) {
+ int r;
+
if (m->ready_sent && m->status_ready)
/* Skip the notification if nothing changed. */
return;
- sd_notifyf(false,
- "%sSTATUS=Ready.",
- m->ready_sent ? "READY=1\n" : "");
+ r = sd_notify(false,
+ "READY=1\n"
+ "STATUS=Ready.");
+ if (r < 0)
+ log_full_errno(m->ready_sent ? LOG_DEBUG : LOG_WARNING, r,
+ "Failed to send readiness notification, ignoring: %m");
+
m->ready_sent = m->status_ready = true;
}
l = recv(fd, &buffer, sizeof(buffer), MSG_DONTWAIT);
if (l < 0) {
- if (IN_SET(errno, EINTR, EAGAIN))
+ if (ERRNO_IS_TRANSIENT(errno))
return 0;
return log_error_errno(errno, "Failed to read from user lookup fd: %m");
[MANAGER_TIMESTAMP_GENERATORS_FINISH] = "generators-finish",
[MANAGER_TIMESTAMP_UNITS_LOAD_START] = "units-load-start",
[MANAGER_TIMESTAMP_UNITS_LOAD_FINISH] = "units-load-finish",
+ [MANAGER_TIMESTAMP_UNITS_LOAD] = "units-load",
[MANAGER_TIMESTAMP_INITRD_SECURITY_START] = "initrd-security-start",
[MANAGER_TIMESTAMP_INITRD_SECURITY_FINISH] = "initrd-security-finish",
[MANAGER_TIMESTAMP_INITRD_GENERATORS_START] = "initrd-generators-start",