/* Let's remove some environment variables that we need ourselves to communicate with our clients */
strv_env_unset_many(
l,
+ "CACHE_DIRECTORY",
+ "CONFIGURATION_DIRECTORY",
"EXIT_CODE",
"EXIT_STATUS",
"INVOCATION_ID",
"LISTEN_FDNAMES",
"LISTEN_FDS",
"LISTEN_PID",
+ "LOGS_DIRECTORY",
"MAINPID",
"MANAGERPID",
"NOTIFY_SOCKET",
"PIDFILE",
"REMOTE_ADDR",
"REMOTE_PORT",
+ "RUNTIME_DIRECTORY",
"SERVICE_RESULT",
+ "STATE_DIRECTORY",
"WATCHDOG_PID",
"WATCHDOG_USEC",
NULL);
.watchdog_overridden[WATCHDOG_REBOOT] = USEC_INFINITY,
.watchdog_overridden[WATCHDOG_KEXEC] = USEC_INFINITY,
+ .show_status_overridden = _SHOW_STATUS_INVALID,
+
.notify_fd = -1,
.cgroups_agent_fd = -1,
.signal_fd = -1,
return n;
}
-static bool manager_unit_cache_needs_refresh(Manager *m) {
- assert(m);
+bool manager_unit_file_maybe_loadable_from_cache(Unit *u) {
+ assert(u);
+
+ if (u->load_state != UNIT_NOT_FOUND)
+ return false;
- return m->unit_cache_mtime > 0 && !lookup_paths_mtime_good(&m->lookup_paths, m->unit_cache_mtime);
+ if (u->manager->unit_cache_mtime == 0)
+ return false;
+
+ if (u->manager->unit_cache_mtime > u->fragment_loadtime)
+ return true;
+
+ return !lookup_paths_mtime_good(&u->manager->lookup_paths, u->manager->unit_cache_mtime);
}
int manager_load_unit_prepare(
* but if they are already referenced (because of dependencies or ordering)
* then we have to force a load of the fragment. As an optimization, check
* first if anything in the usual paths was modified since the last time
- * the cache was loaded. */
- if (ret->load_state == UNIT_NOT_FOUND && manager_unit_cache_needs_refresh(m))
+ * the cache was loaded. Also check if the last time an attempt to load the
+ * unit was made was before the most recent cache refresh, so that we know
+ * we need to try again - even if the cache is current, it might have been
+ * updated in a different context before we had a chance to retry loading
+ * this particular unit. */
+ if (manager_unit_file_maybe_loadable_from_cache(ret))
ret->load_state = UNIT_STUB;
else {
*_ret = ret;
switch (sfsi.ssi_signo - SIGRTMIN) {
case 20:
- manager_set_show_status(m, SHOW_STATUS_YES, "signal");
+ manager_override_show_status(m, SHOW_STATUS_YES, "signal");
break;
case 21:
- manager_set_show_status(m, SHOW_STATUS_NO, "signal");
+ manager_override_show_status(m, SHOW_STATUS_NO, "signal");
break;
case 22:
static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata) {
Manager *m = userdata;
int r;
- uint64_t next;
assert(m);
assert(source);
manager_print_jobs_in_progress(m);
- next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_PERIOD_USEC;
- r = sd_event_source_set_time(source, next);
+ r = sd_event_source_set_time_relative(source, JOBS_IN_PROGRESS_PERIOD_USEC);
if (r < 0)
return r;
/* After switching root, udevd has not been started yet. So, enumeration results should not be emitted. */
(void) serialize_bool(f, "honor-device-enumeration", !switching_root);
- t = show_status_to_string(m->show_status);
- if (t)
- (void) serialize_item(f, "show-status", t);
+ if (m->show_status_overridden != _SHOW_STATUS_INVALID)
+ (void) serialize_item(f, "show-status-overridden",
+ show_status_to_string(m->show_status_overridden));
if (m->log_level_overridden)
(void) serialize_item_format(f, "log-level-override", "%i", log_get_max_level());
m->watchdog[t] = timeout;
}
-int manager_set_watchdog_overridden(Manager *m, WatchdogType t, usec_t timeout) {
+int manager_override_watchdog(Manager *m, WatchdogType t, usec_t timeout) {
int r = 0;
assert(m);
else
m->honor_device_enumeration = b;
- } else if ((val = startswith(l, "show-status="))) {
+ } else if ((val = startswith(l, "show-status-overridden="))) {
ShowStatus s;
s = show_status_from_string(val);
if (s < 0)
- log_notice("Failed to parse show-status flag '%s', ignoring.", val);
+ log_notice("Failed to parse show-status-overridden flag '%s', ignoring.", val);
else
- manager_set_show_status(m, s, "deserialization");
+ manager_override_show_status(m, s, "deserialize");
} else if ((val = startswith(l, "log-level-override="))) {
int level;
if (deserialize_usec(val, &t) < 0)
log_notice("Failed to parse runtime-watchdog-overridden value '%s', ignoring.", val);
else
- manager_set_watchdog_overridden(m, WATCHDOG_RUNTIME, t);
+ manager_override_watchdog(m, WATCHDOG_RUNTIME, t);
} else if ((val = startswith(l, "reboot-watchdog-overridden="))) {
usec_t t;
if (deserialize_usec(val, &t) < 0)
log_notice("Failed to parse reboot-watchdog-overridden value '%s', ignoring.", val);
else
- manager_set_watchdog_overridden(m, WATCHDOG_REBOOT, t);
+ manager_override_watchdog(m, WATCHDOG_REBOOT, t);
} else if ((val = startswith(l, "kexec-watchdog-overridden="))) {
usec_t t;
if (deserialize_usec(val, &t) < 0)
log_notice("Failed to parse kexec-watchdog-overridden value '%s', ignoring.", val);
else
- manager_set_watchdog_overridden(m, WATCHDOG_KEXEC, t);
+ manager_override_watchdog(m, WATCHDOG_KEXEC, t);
} else if (startswith(l, "env=")) {
r = deserialize_environment(l + 4, &m->client_environment);
else if ((val = startswith(l, "destroy-ipc-gid=")))
manager_deserialize_gid_refs_one(m, val);
else if ((val = startswith(l, "exec-runtime=")))
- exec_runtime_deserialize_one(m, val, fds);
+ (void) exec_runtime_deserialize_one(m, val, fds);
else if ((val = startswith(l, "subscribed="))) {
if (strv_extend(&m->deserialized_subscribed, val) < 0)
log_open();
}
+static ShowStatus manager_get_show_status(Manager *m) {
+ assert(m);
+
+ if (MANAGER_IS_USER(m))
+ return _SHOW_STATUS_INVALID;
+
+ if (m->show_status_overridden != _SHOW_STATUS_INVALID)
+ return m->show_status_overridden;
+
+ return m->show_status;
+}
+
+bool manager_get_show_status_on(Manager *m) {
+ assert(m);
+
+ return show_status_on(manager_get_show_status(m));
+}
+
+static void set_show_status_marker(bool b) {
+ if (b)
+ (void) touch("/run/systemd/show-status");
+ else
+ (void) unlink("/run/systemd/show-status");
+}
+
void manager_set_show_status(Manager *m, ShowStatus mode, const char *reason) {
assert(m);
+ assert(reason);
assert(mode >= 0 && mode < _SHOW_STATUS_MAX);
- if (!MANAGER_IS_SYSTEM(m))
+ if (MANAGER_IS_USER(m))
return;
if (mode == m->show_status)
return;
- bool enabled = IN_SET(mode, SHOW_STATUS_TEMPORARY, SHOW_STATUS_YES);
- log_debug("%s (%s) showing of status (%s).",
- enabled ? "Enabling" : "Disabling",
- strna(show_status_to_string(mode)),
- reason);
- m->show_status = mode;
+ if (m->show_status_overridden == _SHOW_STATUS_INVALID) {
+ bool enabled;
- if (enabled)
- (void) touch("/run/systemd/show-status");
- else
- (void) unlink("/run/systemd/show-status");
+ enabled = show_status_on(mode);
+ log_debug("%s (%s) showing of status (%s).",
+ enabled ? "Enabling" : "Disabling",
+ strna(show_status_to_string(mode)),
+ reason);
+
+ set_show_status_marker(enabled);
+ }
+
+ m->show_status = mode;
}
-static bool manager_get_show_status(Manager *m, StatusType type) {
+void manager_override_show_status(Manager *m, ShowStatus mode, const char *reason) {
assert(m);
+ assert(mode < _SHOW_STATUS_MAX);
- if (!MANAGER_IS_SYSTEM(m))
- return false;
+ if (MANAGER_IS_USER(m))
+ return;
- if (m->no_console_output)
- return false;
+ if (mode == m->show_status_overridden)
+ return;
- if (!IN_SET(manager_state(m), MANAGER_INITIALIZING, MANAGER_STARTING, MANAGER_STOPPING))
- return false;
+ m->show_status_overridden = mode;
- /* If we cannot find out the status properly, just proceed. */
- if (type != STATUS_TYPE_EMERGENCY && manager_check_ask_password(m) > 0)
- return false;
+ if (mode == _SHOW_STATUS_INVALID)
+ mode = m->show_status;
- if (type == STATUS_TYPE_NOTICE && m->show_status != SHOW_STATUS_NO)
- return true;
+ log_debug("%s (%s) showing of status (%s).",
+ m->show_status_overridden != _SHOW_STATUS_INVALID ? "Overriding" : "Restoring",
+ strna(show_status_to_string(mode)),
+ reason);
- return show_status_on(m->show_status);
+ set_show_status_marker(show_status_on(mode));
}
const char *manager_get_confirm_spawn(Manager *m) {
return access("/run/systemd/confirm_spawn_disabled", F_OK) >= 0;
}
+static bool manager_should_show_status(Manager *m, StatusType type) {
+ assert(m);
+
+ if (!MANAGER_IS_SYSTEM(m))
+ return false;
+
+ if (m->no_console_output)
+ return false;
+
+ if (!IN_SET(manager_state(m), MANAGER_INITIALIZING, MANAGER_STARTING, MANAGER_STOPPING))
+ return false;
+
+ /* If we cannot find out the status properly, just proceed. */
+ if (type != STATUS_TYPE_EMERGENCY && manager_check_ask_password(m) > 0)
+ return false;
+
+ if (type == STATUS_TYPE_NOTICE && m->show_status != SHOW_STATUS_NO)
+ return true;
+
+ return manager_get_show_status_on(m);
+}
+
void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) {
va_list ap;
/* If m is NULL, assume we're after shutdown and let the messages through. */
- if (m && !manager_get_show_status(m, type))
+ if (m && !manager_should_show_status(m, type))
return;
/* XXX We should totally drop the check for ephemeral here
size = set_size(m->failed_units);
if (failed) {
- r = set_ensure_allocated(&m->failed_units, NULL);
+ r = set_ensure_put(&m->failed_units, NULL, u);
if (r < 0)
return log_oom();
-
- if (set_put(m->failed_units, u) < 0)
- return log_oom();
} else
(void) set_remove(m->failed_units, u);