return set_ensure_put(&u->manager->startup_units, NULL, u);
}
-static int unit_validate_on_failure_job_mode(
- Unit *u,
- const char *job_mode_setting,
- JobMode job_mode,
- const char *dependency_name,
- UnitDependencyAtom atom) {
+static const struct {
+ UnitDependencyAtom atom;
+ size_t job_mode_offset;
+ const char *dependency_name;
+ const char *job_mode_setting_name;
+} on_termination_settings[] = {
+ { UNIT_ATOM_ON_SUCCESS, offsetof(Unit, on_success_job_mode), "OnSuccess=", "OnSuccessJobMode=" },
+ { UNIT_ATOM_ON_FAILURE, offsetof(Unit, on_failure_job_mode), "OnFailure=", "OnFailureJobMode=" },
+};
- Unit *other, *found = NULL;
+static int unit_validate_on_termination_job_modes(Unit *u) {
+ assert(u);
- if (job_mode != JOB_ISOLATE)
- return 0;
+ /* Verify that if On{Success,Failure}JobMode=isolate, only one unit gets specified. */
- UNIT_FOREACH_DEPENDENCY(other, u, atom) {
- if (!found)
- found = other;
- else if (found != other)
- return log_unit_error_errno(
- u, SYNTHETIC_ERRNO(ENOEXEC),
- "More than one %s dependencies specified but %sisolate set. Refusing.",
- dependency_name, job_mode_setting);
+ FOREACH_ELEMENT(setting, on_termination_settings) {
+ JobMode job_mode = *(JobMode*) ((uint8_t*) u + setting->job_mode_offset);
+
+ if (job_mode != JOB_ISOLATE)
+ continue;
+
+ Unit *other, *found = NULL;
+ UNIT_FOREACH_DEPENDENCY(other, u, setting->atom) {
+ if (!found)
+ found = other;
+ else if (found != other)
+ return log_unit_error_errno(u, SYNTHETIC_ERRNO(ENOEXEC),
+ "More than one %s dependencies specified but %sisolate set. Refusing.",
+ setting->dependency_name, setting->job_mode_setting_name);
+ }
}
return 0;
if (r < 0)
goto fail;
- r = unit_validate_on_failure_job_mode(u, "OnSuccessJobMode=", u->on_success_job_mode, "OnSuccess=", UNIT_ATOM_ON_SUCCESS);
- if (r < 0)
- goto fail;
-
- r = unit_validate_on_failure_job_mode(u, "OnFailureJobMode=", u->on_failure_job_mode, "OnFailure=", UNIT_ATOM_ON_FAILURE);
+ r = unit_validate_on_termination_job_modes(u);
if (r < 0)
goto fail;
(void) manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, NULL, NULL, NULL);
}
-void unit_start_on_failure(
- Unit *u,
- const char *dependency_name,
- UnitDependencyAtom atom,
- JobMode job_mode) {
-
- int n_jobs = -1;
- Unit *other;
+void unit_start_on_termination_deps(Unit *u, UnitDependencyAtom atom) {
+ const char *dependency_name = NULL;
+ JobMode job_mode;
+ unsigned n_jobs = 0;
int r;
+ /* Act on OnFailure= and OnSuccess= dependencies */
+
assert(u);
- assert(dependency_name);
+ assert(u->manager);
assert(IN_SET(atom, UNIT_ATOM_ON_SUCCESS, UNIT_ATOM_ON_FAILURE));
- /* Act on OnFailure= and OnSuccess= dependencies */
+ FOREACH_ELEMENT(setting, on_termination_settings)
+ if (atom == setting->atom) {
+ job_mode = *(JobMode*) ((uint8_t*) u + setting->job_mode_offset);
+ dependency_name = setting->dependency_name;
+ break;
+ }
+
+ assert(dependency_name);
+ Unit *other;
UNIT_FOREACH_DEPENDENCY(other, u, atom) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- if (n_jobs < 0) {
+ if (n_jobs == 0)
log_unit_info(u, "Triggering %s dependencies.", dependency_name);
- n_jobs = 0;
- }
r = manager_add_job(u->manager, JOB_START, other, job_mode, NULL, &error, NULL);
if (r < 0)
- log_unit_warning_errno(
- u, r, "Failed to enqueue %s job, ignoring: %s",
- dependency_name, bus_error_message(&error, r));
+ log_unit_warning_errno(u, r, "Failed to enqueue %s%s job, ignoring: %s",
+ dependency_name, other->id, bus_error_message(&error, r));
n_jobs++;
}
- if (n_jobs >= 0)
- log_unit_debug(u, "Triggering %s dependencies done (%i %s).",
+ if (n_jobs > 0)
+ log_unit_debug(u, "Triggering %s dependencies done (%u %s).",
dependency_name, n_jobs, n_jobs == 1 ? "job" : "jobs");
}
}
if (ns == UNIT_INACTIVE && !IN_SET(os, UNIT_FAILED, UNIT_INACTIVE, UNIT_MAINTENANCE))
- unit_start_on_failure(u, "OnSuccess=", UNIT_ATOM_ON_SUCCESS, u->on_success_job_mode);
+ unit_start_on_termination_deps(u, UNIT_ATOM_ON_SUCCESS);
else if (ns != os && ns == UNIT_FAILED)
- unit_start_on_failure(u, "OnFailure=", UNIT_ATOM_ON_FAILURE, u->on_failure_job_mode);
+ unit_start_on_termination_deps(u, UNIT_ATOM_ON_FAILURE);
}
manager_recheck_journal(m);