]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/job.c
core: when we uninstall a job, add unit to dbus queue
[thirdparty/systemd.git] / src / core / job.c
index 2a630356bfa5738bf6994b70c5ac693180c88ef8..59bb9d2162c610a037d3f94f4ff7149c5d58ab6d 100644 (file)
@@ -89,7 +89,7 @@ void job_unlink(Job *j) {
         j->timer_event_source = sd_event_source_unref(j->timer_event_source);
 }
 
-void job_free(Job *j) {
+Job* job_free(Job *j) {
         assert(j);
         assert(!j->installed);
         assert(!j->transaction_prev);
@@ -102,7 +102,7 @@ void job_free(Job *j) {
         sd_bus_track_unref(j->bus_track);
         strv_free(j->deserialized_clients);
 
-        free(j);
+        return mfree(j);
 }
 
 static void job_set_state(Job *j, JobState state) {
@@ -151,7 +151,9 @@ void job_uninstall(Job *j) {
 
         unit_add_to_gc_queue(j->unit);
 
-        hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id));
+        unit_add_to_dbus_queue(j->unit); /* The Job property of the unit has changed now */
+
+        hashmap_remove_value(j->manager->jobs, UINT32_TO_PTR(j->id), j);
         j->installed = false;
 }
 
@@ -206,8 +208,9 @@ Job* job_install(Job *j) {
                             (job_type_allows_late_merge(j->type) && job_type_is_superset(uj->type, j->type))) {
                                 job_merge_into_installed(uj, j);
                                 log_unit_debug(uj->unit,
-                                               "Merged into installed job %s/%s as %u",
-                                               uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id);
+                                               "Merged %s/%s into installed job %s/%s as %"PRIu32,
+                                               j->unit->id, job_type_to_string(j->type), uj->unit->id,
+                                               job_type_to_string(uj->type), uj->id);
                                 return uj;
                         } else {
                                 /* already running and not safe to merge into */
@@ -216,8 +219,8 @@ Job* job_install(Job *j) {
                                  * not currently possible to have more than one installed job per unit. */
                                 job_merge_into_installed(uj, j);
                                 log_unit_debug(uj->unit,
-                                               "Merged into running job, re-running: %s/%s as %u",
-                                               uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id);
+                                               "Merged into running job, re-running: %s/%s as %"PRIu32,
+                                               uj->unit->id, job_type_to_string(uj->type), uj->id);
 
                                 job_set_state(uj, JOB_WAITING);
                                 return uj;
@@ -236,28 +239,36 @@ Job* job_install(Job *j) {
 
         job_add_to_gc_queue(j);
 
+        job_add_to_dbus_queue(j); /* announce this job to clients */
+        unit_add_to_dbus_queue(j->unit); /* The Job property of the unit has changed now */
+
         return j;
 }
 
 int job_install_deserialized(Job *j) {
         Job **pj;
+        int r;
 
         assert(!j->installed);
 
         if (j->type < 0 || j->type >= _JOB_TYPE_MAX_IN_TRANSACTION)
-                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+                return log_unit_debug_errno(j->unit, SYNTHETIC_ERRNO(EINVAL),
                                        "Invalid job type %s in deserialization.",
                                        strna(job_type_to_string(j->type)));
 
         pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
-        if (*pj) {
-                log_unit_debug(j->unit, "Unit already has a job installed. Not installing deserialized job.");
-                return -EEXIST;
-        }
+        if (*pj)
+                return log_unit_debug_errno(j->unit, SYNTHETIC_ERRNO(EEXIST),
+                                            "Unit already has a job installed. Not installing deserialized job.");
+
+        r = hashmap_put(j->manager->jobs, UINT32_TO_PTR(j->id), j);
+        if (r == -EEXIST)
+                return log_unit_debug_errno(j->unit, r, "Job ID %" PRIu32 " already used, cannot deserialize job.", j->id);
+        if (r < 0)
+                return log_unit_debug_errno(j->unit, r, "Failed to insert job into jobs hash table: %m");
 
         *pj = j;
         j->installed = true;
-        j->reloaded = true;
 
         if (j->state == JOB_RUNNING)
                 j->unit->manager->n_running_jobs++;
@@ -306,7 +317,7 @@ void job_dependency_free(JobDependency *l) {
         free(l);
 }
 
-void job_dump(Job *j, FILE*f, const char *prefix) {
+void job_dump(Job *j, FILE *f, const char *prefix) {
         assert(j);
         assert(f);
 
@@ -965,19 +976,6 @@ static void job_fail_dependencies(Unit *u, UnitDependency d) {
         }
 }
 
-static int job_save_pending_finished_job(Job *j) {
-        int r;
-
-        assert(j);
-
-        r = set_ensure_allocated(&j->manager->pending_finished_jobs, NULL);
-        if (r < 0)
-                return r;
-
-        job_unlink(j);
-        return set_put(j->manager->pending_finished_jobs, j);
-}
-
 int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool already) {
         Unit *u;
         Unit *other;
@@ -1017,11 +1015,7 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool alr
                 j->manager->n_failed_jobs++;
 
         job_uninstall(j);
-        /* Keep jobs started before the reload to send singal later, free all others */
-        if (!MANAGER_IS_RELOADING(j->manager) ||
-            !j->reloaded ||
-            job_save_pending_finished_job(j) < 0)
-                job_free(j);
+        job_free(j);
 
         /* Fail depending jobs on failure */
         if (result != JOB_DONE && recursive) {