if (delete) {
- log_warning("Breaking ordering cycle by deleting job %s/%s", k->unit->meta.id, job_type_to_string(k->type));
+ log_warning("Breaking ordering cycle by deleting job %s/%s", delete->unit->meta.id, job_type_to_string(delete->type));
transaction_delete_unit(m, delete->unit);
return -EAGAIN;
}
log_error("Unable to break cycle");
- dbus_set_error(e, BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC, "Transaction order is cyclic. See logs for details.");
+ dbus_set_error(e, BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC, "Transaction order is cyclic. See system logs for details.");
return -ENOEXEC;
}
j->unit->meta.job = j;
j->installed = true;
+ m->n_installed_jobs ++;
/* We're fully installed. Now let's free data we don't
* need anymore. */
assert(type < _JOB_TYPE_MAX);
assert(unit);
- if (unit->meta.load_state != UNIT_LOADED && unit->meta.load_state != UNIT_FAILED) {
+ if (unit->meta.load_state != UNIT_LOADED && unit->meta.load_state != UNIT_ERROR) {
dbus_set_error(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->meta.id);
return -EINVAL;
}
- if (type != JOB_STOP && unit->meta.load_state == UNIT_FAILED) {
- dbus_set_error(e, BUS_ERROR_LOAD_FAILED, "Unit %s failed to load: %s. You might find more information in the logs.",
+ if (type != JOB_STOP && unit->meta.load_state == UNIT_ERROR) {
+ dbus_set_error(e, BUS_ERROR_LOAD_FAILED, "Unit %s failed to load: %s. You might find more information in the system logs.",
unit->meta.id,
strerror(-unit->meta.load_error));
return -EINVAL;
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, !override, override, false, e, NULL)) < 0 && r != -EBADR) {
log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r));
- dbus_error_free(e);
+
+ if (e)
+ dbus_error_free(e);
}
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_WANTS], i)
if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, false, false, false, e, NULL)) < 0) {
log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r));
- dbus_error_free(e);
+
+ if (e)
+ dbus_error_free(e);
}
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUISITE], i)
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, !override, override, false, e, NULL)) < 0 && r != -EBADR) {
log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r));
- dbus_error_free(e);
+
+ if (e)
+ dbus_error_free(e);
}
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_CONFLICTS], i)
continue;
/* No need to stop inactive jobs */
- if (UNIT_IS_INACTIVE_OR_MAINTENANCE(unit_active_state(u)))
+ if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(u)))
continue;
/* Is there already something listed for this? */
return -EPERM;
}
- log_debug("Trying to enqueue job %s/%s", unit->meta.id, job_type_to_string(type));
+ log_debug("Trying to enqueue job %s/%s/%s", unit->meta.id, job_type_to_string(type), job_mode_to_string(mode));
if ((r = transaction_add_job_and_dependencies(m, type, unit, NULL, true, override, false, e, &ret)) < 0) {
transaction_abort(m);
set_free_free(m->unit_path_cache);
m->unit_path_cache = NULL;
+ manager_check_finished(m);
+
/* There might still be some zombies hanging around from
* before we were exec()'ed. Leat's reap them */
if ((r = manager_dispatch_sigchld(m)) < 0)
return false;
}
-void manager_reset_maintenance(Manager *m) {
+void manager_reset_failed(Manager *m) {
Unit *u;
Iterator i;
assert(m);
HASHMAP_FOREACH(u, m->units, i)
- unit_reset_maintenance(u);
+ unit_reset_failed(u);
}
int manager_set_console(Manager *m, const char *console) {
return 0;
}
+bool manager_unit_pending_inactive(Manager *m, const char *name) {
+ Unit *u;
+
+ assert(m);
+ assert(name);
+
+ /* Returns true if the unit is inactive or going down */
+ if (!(u = manager_get_unit(m, name)))
+ return true;
+
+ return unit_pending_inactive(u);
+}
+
+void manager_check_finished(Manager *m) {
+ char userspace[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
+
+ assert(m);
+
+ if (dual_timestamp_is_set(&m->finish_timestamp))
+ return;
+
+ if (hashmap_size(m->jobs) > 0)
+ return;
+
+ dual_timestamp_get(&m->finish_timestamp);
+
+ if (m->running_as == MANAGER_SYSTEM)
+ log_info("Startup finished in %s (kernel) + %s (userspace) = %s.",
+ format_timespan(kernel, sizeof(kernel),
+ m->startup_timestamp.monotonic),
+ format_timespan(userspace, sizeof(userspace),
+ m->finish_timestamp.monotonic - m->startup_timestamp.monotonic),
+ format_timespan(sum, sizeof(sum),
+ m->finish_timestamp.monotonic));
+ else
+ log_debug("Startup finished in %s.",
+ format_timespan(userspace, sizeof(userspace),
+ m->finish_timestamp.monotonic - m->startup_timestamp.monotonic));
+
+}
+
static const char* const manager_running_as_table[_MANAGER_RUNNING_AS_MAX] = {
[MANAGER_SYSTEM] = "system",
[MANAGER_SESSION] = "session"