/* Ok, we can drop one, so let's do so. */
log_debug_unit(d->unit->id,
- "Fixing conflicting jobs by deleting job %s/%s",
+ "Fixing conflicting jobs %s/%s,%s/%s by deleting job %s/%s",
+ j->unit->id, job_type_to_string(j->type),
+ k->unit->id, job_type_to_string(k->type),
d->unit->id, job_type_to_string(d->type));
transaction_delete_job(tr, d, true);
return 0;
return -EAGAIN;
/* We couldn't merge anything. Failure */
- sd_bus_error_setf(
- e, BUS_ERROR_TRANSACTION_JOBS_CONFLICTING, "Transaction contains conflicting jobs '%s' and '%s' for %s. Probably contradicting requirement dependencies configured.",
- job_type_to_string(t), job_type_to_string(k->type), k->unit->id);
+ sd_bus_error_setf(e, BUS_ERROR_TRANSACTION_JOBS_CONFLICTING,
+ "Transaction contains conflicting jobs '%s' and '%s' for %s. "
+ "Probably contradicting requirement dependencies configured.",
+ job_type_to_string(t),
+ job_type_to_string(k->type),
+ k->unit->id);
return r;
}
}
"Found dependency on %s/%s",
k->unit->id, job_type_to_string(k->type));
- if (!delete &&
+ if (!delete && hashmap_get(tr->jobs, k->unit) &&
!unit_matters_to_anchor(k->unit, k)) {
/* Ok, we can drop this one, so let's
* do so. */
if (j->unit->job && (mode == JOB_FAIL || j->unit->job->irreversible) &&
!job_type_is_superset(j->type, j->unit->job->type)) {
- sd_bus_error_setf(e, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE, "Transaction is destructive.");
+ sd_bus_error_setf(e, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE,
+ "Transaction is destructive.");
return -EEXIST;
}
}
/* Moves the transaction jobs to the set of active jobs */
- if (mode == JOB_ISOLATE) {
+ if (mode == JOB_ISOLATE || mode == JOB_FLUSH) {
/* When isolating first kill all installed jobs which
* aren't part of the new transaction */
unit->load_state != UNIT_ERROR &&
unit->load_state != UNIT_NOT_FOUND &&
unit->load_state != UNIT_MASKED) {
- sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->id);
+ sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED,
+ "Unit %s is not loaded properly.", unit->id);
return -EINVAL;
}
if (type != JOB_STOP && unit->load_state == UNIT_ERROR) {
- sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED,
- "Unit %s failed to load: %s. "
- "See system logs and 'systemctl status %s' for details.",
- unit->id,
- strerror(-unit->load_error),
- unit->id);
+ if (unit->load_error == -ENOENT || unit->manager->test_run)
+ sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED,
+ "Unit %s failed to load: %s.",
+ unit->id,
+ strerror(-unit->load_error));
+ else
+ sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED,
+ "Unit %s failed to load: %s. "
+ "See system logs and 'systemctl status %s' for details.",
+ unit->id,
+ strerror(-unit->load_error),
+ unit->id);
return -EINVAL;
}
if (type != JOB_STOP && unit->load_state == UNIT_NOT_FOUND) {
sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED,
- "Unit %s failed to load: %s.",
- unit->id,
- strerror(-unit->load_error));
+ "Unit %s failed to load: %s.",
+ unit->id, strerror(-unit->load_error));
return -EINVAL;
}
if (type != JOB_STOP && unit->load_state == UNIT_MASKED) {
- sd_bus_error_setf(e, BUS_ERROR_UNIT_MASKED, "Unit %s is masked.", unit->id);
+ sd_bus_error_setf(e, BUS_ERROR_UNIT_MASKED,
+ "Unit %s is masked.", unit->id);
return -EADDRNOTAVAIL;
}
if (!unit_job_is_applicable(unit, type)) {
- sd_bus_error_setf(e, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE, "Job type %s is not applicable for unit %s.", job_type_to_string(type), unit->id);
+ sd_bus_error_setf(e, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE,
+ "Job type %s is not applicable for unit %s.",
+ job_type_to_string(type), unit->id);
return -EBADR;
}
if (!tr)
return NULL;
- tr->jobs = hashmap_new(trivial_hash_func, trivial_compare_func);
+ tr->jobs = hashmap_new(NULL);
if (!tr->jobs) {
free(tr);
return NULL;