transaction_delete_job(m, j);
}
+static void transaction_clean_dependencies(Manager *m) {
+ Iterator i;
+ Job *j;
+
+ assert(m);
+
+ /* Drops all dependencies of all installed jobs */
+
+ HASHMAP_FOREACH(j, m->jobs, i) {
+ while (j->subject_list)
+ job_dependency_free(j->subject_list);
+ while (j->object_list)
+ job_dependency_free(j->object_list);
+ }
+
+ assert(!m->transaction_anchor);
+}
+
static void transaction_abort(Manager *m) {
Job *j;
job_free(j);
assert(hashmap_isempty(m->transaction_jobs));
- assert(!m->transaction_anchor);
+
+ transaction_clean_dependencies(m);
}
static void transaction_find_jobs_that_matter_to_anchor(Manager *m, Job *j, unsigned generation) {
assert(!j->transaction_next);
assert(!j->transaction_prev);
- while (j->subject_list)
- job_dependency_free(j->subject_list);
- while (j->object_list)
- job_dependency_free(j->object_list);
}
- m->transaction_anchor = NULL;
+ /* As last step, kill all remaining job dependencies. */
+ transaction_clean_dependencies(m);
return 0;
m->dispatching_load_queue = false;
}
-int manager_load_unit(Manager *m, const char *name, Unit **_ret) {
+int manager_load_unit(Manager *m, const char *path, Unit **_ret) {
Unit *ret;
int r;
+ const char *name;
assert(m);
- assert(name);
+ assert(path);
assert(_ret);
/* This will load the service information files, but not actually
- * start any services or anything */
+ * start any services or anything. */
+
+ name = file_name_from_path(path);
if ((ret = manager_get_unit(m, name))) {
*_ret = ret;
if (!(ret = unit_new(m)))
return -ENOMEM;
+ if (is_path(path)) {
+ if (!(ret->meta.load_path = strdup(path))) {
+ unit_free(ret);
+ return -ENOMEM;
+ }
+ }
+
if ((r = unit_add_name(ret, name)) < 0) {
unit_free(ret);
return r;