u->deserialized_job = _JOB_TYPE_INVALID;
u->default_dependencies = true;
u->unit_file_state = _UNIT_FILE_STATE_INVALID;
+ u->unit_file_preset = -1;
u->on_failure_job_mode = JOB_REPLACE;
return u;
goto fail;
if (u->on_failure_job_mode == JOB_ISOLATE && set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
- log_error_unit(u->id, "More than one OnFailure= dependencies specified for %s but OnFailureJobMode=isolate set. Refusing.", u->id);
+ log_unit_error(u->id, "More than one OnFailure= dependencies specified for %s but OnFailureJobMode=isolate set. Refusing.", u->id);
r = -EINVAL;
goto fail;
}
unit_add_to_dbus_queue(u);
unit_add_to_gc_queue(u);
- log_debug_unit(u->id, "Failed to load configuration for %s: %s",
+ log_unit_debug(u->id, "Failed to load configuration for %s: %s",
u->id, strerror(-r));
return r;
}
+static bool unit_condition_test_list(Unit *u, Condition *first, const char *(*to_string)(ConditionType t)) {
+ Condition *c;
+ int triggered = -1;
+
+ assert(u);
+ assert(to_string);
+
+ /* If the condition list is empty, then it is true */
+ if (!first)
+ return true;
+
+ /* Otherwise, if all of the non-trigger conditions apply and
+ * if any of the trigger conditions apply (unless there are
+ * none) we return true */
+ LIST_FOREACH(conditions, c, first) {
+ int r;
+
+ r = condition_test(c);
+ if (r < 0)
+ log_unit_warning(u->id,
+ "Couldn't determine result for %s=%s%s%s for %s, assuming failed: %s",
+ to_string(c->type),
+ c->trigger ? "|" : "",
+ c->negate ? "!" : "",
+ c->parameter,
+ u->id,
+ strerror(-r));
+ else
+ log_unit_debug(u->id,
+ "%s=%s%s%s %s for %s.",
+ to_string(c->type),
+ c->trigger ? "|" : "",
+ c->negate ? "!" : "",
+ c->parameter,
+ condition_result_to_string(c->result),
+ u->id);
+
+ if (!c->trigger && r <= 0)
+ return false;
+
+ if (c->trigger && triggered <= 0)
+ triggered = r > 0;
+ }
+
+ return triggered != 0;
+}
+
static bool unit_condition_test(Unit *u) {
assert(u);
dual_timestamp_get(&u->condition_timestamp);
- u->condition_result = condition_test_list(u->id, u->conditions, condition_type_to_string);
+ u->condition_result = unit_condition_test_list(u, u->conditions, condition_type_to_string);
return u->condition_result;
}
assert(u);
dual_timestamp_get(&u->assert_timestamp);
- u->assert_result = condition_test_list(u->id, u->asserts, assert_type_to_string);
+ u->assert_result = unit_condition_test_list(u, u->asserts, assert_type_to_string);
return u->assert_result;
}
t == JOB_STOP ? SD_MESSAGE_UNIT_STOPPING :
SD_MESSAGE_UNIT_RELOADING;
- log_struct_unit(LOG_INFO,
- u->id,
- MESSAGE_ID(mid),
- "MESSAGE=%s", buf,
+ log_unit_struct(u->id,
+ LOG_INFO,
+ LOG_MESSAGE_ID(mid),
+ LOG_MESSAGE("%s", buf),
NULL);
}
* but we don't want to recheck the condition in that case. */
if (state != UNIT_ACTIVATING &&
!unit_condition_test(u)) {
- log_debug_unit(u->id, "Starting of %s requested but condition failed. Not starting unit.", u->id);
+ log_unit_debug(u->id, "Starting of %s requested but condition failed. Not starting unit.", u->id);
return -EALREADY;
}
/* If the asserts failed, fail the entire job */
if (state != UNIT_ACTIVATING &&
!unit_assert_test(u)) {
- log_debug_unit(u->id, "Starting of %s requested but asserts failed.", u->id);
+ log_unit_debug(u->id, "Starting of %s requested but asserts failed.", u->id);
return -EPROTO;
}
/* Forward to the main object, if we aren't it. */
following = unit_following(u);
if (following) {
- log_debug_unit(u->id, "Redirecting start request from %s to %s.", u->id, following->id);
+ log_unit_debug(u->id, "Redirecting start request from %s to %s.", u->id, following->id);
return unit_start(following);
}
return -EALREADY;
if ((following = unit_following(u))) {
- log_debug_unit(u->id, "Redirecting stop request from %s to %s.",
+ log_unit_debug(u->id, "Redirecting stop request from %s to %s.",
u->id, following->id);
return unit_stop(following);
}
return -EALREADY;
if (state != UNIT_ACTIVE) {
- log_warning_unit(u->id, "Unit %s cannot be reloaded because it is inactive.",
+ log_unit_warning(u->id, "Unit %s cannot be reloaded because it is inactive.",
u->id);
return -ENOEXEC;
}
following = unit_following(u);
if (following) {
- log_debug_unit(u->id, "Redirecting reload request from %s to %s.",
+ log_unit_debug(u->id, "Redirecting reload request from %s to %s.",
u->id, following->id);
return unit_reload(following);
}
if (unit_active_or_pending(other))
return;
- log_info_unit(u->id, "Unit %s is not needed anymore. Stopping.", u->id);
+ log_unit_info(u->id, "Unit %s is not needed anymore. Stopping.", u->id);
/* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
if (!stop)
return;
- log_info_unit(u->id, "Unit %s is bound to inactive service. Stopping, too.", u->id);
+ log_unit_info(u->id, "Unit %s is bound to inactive service. Stopping, too.", u->id);
/* A unit we need to run is gone. Sniff. Let's stop this. */
manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0)
return;
- log_info_unit(u->id, "Triggering OnFailure= dependencies of %s.", u->id);
+ log_unit_info(u->id, "Triggering OnFailure= dependencies of %s.", u->id);
SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) {
int r;
r = manager_add_job(u->manager, JOB_START, other, u->on_failure_job_mode, true, NULL, NULL);
if (r < 0)
- log_error_unit(u->id, "Failed to enqueue OnFailure= job: %s", strerror(-r));
+ log_unit_error_errno(u->id, r, "Failed to enqueue OnFailure= job: %m");
}
}
/* Make sure the cgroup is always removed when we become inactive */
if (UNIT_IS_INACTIVE_OR_FAILED(ns))
- unit_destroy_cgroup(u);
+ unit_destroy_cgroup_if_empty(u);
/* Note that this doesn't apply to RemainAfterExit services exiting
* successfully, since there's no change of state in that case. Which is
check_unneeded_dependencies(u);
if (ns != os && ns == UNIT_FAILED) {
- log_notice_unit(u->id, "Unit %s entered failed state.", u->id);
+ log_unit_notice(u->id, "Unit %s entered failed state.", u->id);
unit_start_on_failure(u);
}
}
case UNIT_TRIGGERS:
case UNIT_TRIGGERED_BY:
if (streq_ptr(id, other))
- log_warning_unit(id, "Dependency %s=%s dropped from unit %s",
+ log_unit_warning(id, "Dependency %s=%s dropped from unit %s",
unit_dependency_to_string(dependency), id, other);
else
- log_warning_unit(id, "Dependency %s=%s dropped from unit %s merged into %s",
+ log_unit_warning(id, "Dependency %s=%s dropped from unit %s merged into %s",
unit_dependency_to_string(dependency), id,
strna(other), id);
return -EINVAL;
return u->unit_file_state;
}
+int unit_get_unit_file_preset(Unit *u) {
+ assert(u);
+
+ if (u->unit_file_preset < 0 && u->fragment_path)
+ u->unit_file_preset = unit_file_query_preset(
+ u->manager->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
+ NULL, basename(u->fragment_path));
+
+ return u->unit_file_preset;
+}
+
Unit* unit_ref_set(UnitRef *ref, Unit *u) {
assert(ref);
assert(u);
_cleanup_free_ char *comm = NULL;
get_process_comm(main_pid, &comm);
- log_warning_unit(u->id, "Failed to kill main process " PID_FMT " (%s): %s", main_pid, strna(comm), strerror(-r));
+ log_unit_warning_errno(u->id, r, "Failed to kill main process " PID_FMT " (%s): %m", main_pid, strna(comm));
} else {
if (!main_pid_alien)
wait_for_exit = true;
_cleanup_free_ char *comm = NULL;
get_process_comm(control_pid, &comm);
- log_warning_unit(u->id, "Failed to kill control process " PID_FMT " (%s): %s", control_pid, strna(comm), strerror(-r));
+ log_unit_warning_errno(u->id, r, "Failed to kill control process " PID_FMT " (%s): %m", control_pid, strna(comm));
} else {
wait_for_exit = true;
r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, sig, true, true, false, pid_set);
if (r < 0) {
if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
- log_warning_unit(u->id, "Failed to kill control group: %s", strerror(-r));
+ log_unit_warning_errno(u->id, r, "Failed to kill control group: %m");
} else if (r > 0) {
/* FIXME: For now, we will not wait for the