#include "dbus-job.h"
#include "dbus-manager.h"
#include "bus-kernel.h"
+#include "time-util.h"
/* As soon as 5s passed since a unit was added to our GC queue, make sure to run a gc sweep */
#define GC_QUEUE_USEC_MAX (10*USEC_PER_SEC)
#define JOBS_IN_PROGRESS_PERIOD_USEC (USEC_PER_SEC / 3)
#define JOBS_IN_PROGRESS_PERIOD_DIVISOR 3
-#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
-
static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
return r;
/* Process signals a bit earlier than the rest of things, but
- * later that notify_fd processing, so that the notify
+ * later than notify_fd processing, so that the notify
* processing can still figure out to which process/service a
* message belongs, before we reap the process. */
r = sd_event_source_set_priority(m->signal_event_source, -5);
m->exit_code = _MANAGER_EXIT_CODE_INVALID;
m->default_timer_accuracy_usec = USEC_PER_MINUTE;
m->start_timeout_usec = DEFAULT_MANAGER_START_TIMEOUT_USEC;
- m->start_timeout_action = FAILURE_ACTION_REBOOT_FORCE;
+ m->start_timeout_action = FAILURE_ACTION_POWEROFF_FORCE;
m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] = m->idle_pipe[3] = -1;
if (r < 0)
goto fail;
- r = hashmap_ensure_allocated(&m->units, string_hash_func, string_compare_func);
+ r = hashmap_ensure_allocated(&m->units, &string_hash_ops);
if (r < 0)
goto fail;
- r = hashmap_ensure_allocated(&m->jobs, trivial_hash_func, trivial_compare_func);
+ r = hashmap_ensure_allocated(&m->jobs, NULL);
if (r < 0)
goto fail;
- r = hashmap_ensure_allocated(&m->cgroup_unit, string_hash_func, string_compare_func);
+ r = hashmap_ensure_allocated(&m->cgroup_unit, &string_hash_ops);
if (r < 0)
goto fail;
- r = hashmap_ensure_allocated(&m->watch_bus, string_hash_func, string_compare_func);
+ r = hashmap_ensure_allocated(&m->watch_bus, &string_hash_ops);
if (r < 0)
goto fail;
- r = set_ensure_allocated(&m->startup_units, trivial_hash_func, trivial_compare_func);
+ r = set_ensure_allocated(&m->startup_units, NULL);
if (r < 0)
goto fail;
- r = set_ensure_allocated(&m->failed_units, trivial_hash_func, trivial_compare_func);
+ r = set_ensure_allocated(&m->failed_units, NULL);
if (r < 0)
goto fail;
r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
if (r < 0) {
log_error("bind(%s) failed: %m", sa.un.sun_path);
- return -errno;
+ if (errno == EADDRINUSE) {
+ log_notice("Removing %s socket and trying again.", m->notify_socket);
+ r = unlink(m->notify_socket);
+ if (r < 0) {
+ log_error("Failed to remove %s: %m", m->notify_socket);
+ return -EADDRINUSE;
+ }
+
+ r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
+ if (r < 0) {
+ log_error("bind(%s) failed: %m", sa.un.sun_path);
+ return -errno;
+ }
+ } else
+ return -errno;
}
r = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
static void manager_build_unit_path_cache(Manager *m) {
char **i;
- _cleanup_free_ DIR *d = NULL;
+ _cleanup_closedir_ DIR *d = NULL;
int r;
assert(m);
set_free_free(m->unit_path_cache);
- m->unit_path_cache = set_new(string_hash_func, string_compare_func);
+ m->unit_path_cache = set_new(&string_hash_ops);
if (!m->unit_path_cache) {
log_error("Failed to allocate unit path cache.");
return;
uint32_t id;
if (safe_atou32(l+15, &id) < 0)
- log_debug("Failed to parse current job id value %s", l+15);
+ log_warning("Failed to parse current job id value %s", l+15);
else
m->current_job_id = MAX(m->current_job_id, id);
uint32_t n;
if (safe_atou32(l+17, &n) < 0)
- log_debug("Failed to parse installed jobs counter %s", l+17);
+ log_warning("Failed to parse installed jobs counter %s", l+17);
else
m->n_installed_jobs += n;
uint32_t n;
if (safe_atou32(l+14, &n) < 0)
- log_debug("Failed to parse failed jobs counter %s", l+14);
+ log_warning("Failed to parse failed jobs counter %s", l+14);
else
m->n_failed_jobs += n;
b = parse_boolean(l+10);
if (b < 0)
- log_debug("Failed to parse taint /usr flag %s", l+10);
+ log_warning("Failed to parse taint /usr flag %s", l+10);
else
m->taint_usr = m->taint_usr || b;
int fd;
if (safe_atoi(l + 10, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
- log_debug("Failed to parse notify fd: %s", l + 10);
+ log_warning("Failed to parse notify fd: %s", l + 10);
else {
m->notify_event_source = sd_event_source_unref(m->notify_event_source);
safe_close(m->notify_fd);
int fd;
if (safe_atoi(l + 9, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
- log_debug("Failed to parse kdbus fd: %s", l + 9);
+ log_warning("Failed to parse kdbus fd: %s", l + 9);
else {
safe_close(m->kdbus_fd);
m->kdbus_fd = fdset_remove(fds, fd);
}
} else if (bus_track_deserialize_item(&m->deserialized_subscribed, l) == 0)
- log_debug("Unknown serialization item '%s'", l);
+ log_warning("Unknown serialization item '%s'", l);
}
for (;;) {
if (!strv_isempty(plus)) {
b = strv_env_merge(2, l, plus);
- if (!b)
+ if (!b) {
+ strv_free(a);
return -ENOMEM;
+ }
l = b;
}
if (m->no_console_output)
return false;
- if (!IN_SET(manager_state(m), MANAGER_STARTING, MANAGER_STOPPING))
+ if (!IN_SET(manager_state(m), MANAGER_INITIALIZING, MANAGER_STARTING, MANAGER_STOPPING))
return false;
if (m->show_status > 0)
assert(m);
/* Did we ever finish booting? If not then we are still starting up */
- if (!dual_timestamp_is_set(&m->finish_timestamp))
+ if (!dual_timestamp_is_set(&m->finish_timestamp)) {
+
+ u = manager_get_unit(m, SPECIAL_BASIC_TARGET);
+ if (!u || !UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u)))
+ return MANAGER_INITIALIZING;
+
return MANAGER_STARTING;
+ }
/* Is the special shutdown target queued? If so, we are in shutdown state */
u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
}
static const char *const manager_state_table[_MANAGER_STATE_MAX] = {
+ [MANAGER_INITIALIZING] = "initializing",
[MANAGER_STARTING] = "starting",
[MANAGER_RUNNING] = "running",
[MANAGER_DEGRADED] = "degraded",