X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Funit.c;h=c08091942e4728fc5561cccf4216f50a3aadfb40;hb=b410e6b951695847619d18952bb9e2622c8b2bbf;hp=57b3b77954adc8456d60ff3e8a8a9257221a7b5f;hpb=01f78473b104d28db0fa813414092bc6358ae521;p=elogind.git diff --git a/src/unit.c b/src/unit.c index 57b3b7795..c08091942 100644 --- a/src/unit.c +++ b/src/unit.c @@ -67,6 +67,7 @@ Unit *unit_new(Manager *m) { u->meta.manager = m; u->meta.type = _UNIT_TYPE_INVALID; + u->meta.deserialized_job = _JOB_TYPE_INVALID; return u; } @@ -968,56 +969,54 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { * failed previously due to EAGAIN. */ job_add_to_run_queue(u->meta.job); - else { - assert(u->meta.job->state == JOB_RUNNING); - /* Let's check whether this state change - * constitutes a finished job, or maybe - * cotradicts a running job and hence needs to - * invalidate jobs. */ + /* Let's check whether this state change constitutes a + * finished job, or maybe cotradicts a running job and + * hence needs to invalidate jobs. */ - switch (u->meta.job->type) { + switch (u->meta.job->type) { - case JOB_START: - case JOB_VERIFY_ACTIVE: + case JOB_START: + case JOB_VERIFY_ACTIVE: - if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) - job_finish_and_invalidate(u->meta.job, true); - else if (ns != UNIT_ACTIVATING) { - unexpected = true; - job_finish_and_invalidate(u->meta.job, false); - } + if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) + job_finish_and_invalidate(u->meta.job, true); + else if (u->meta.job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) { + unexpected = true; + job_finish_and_invalidate(u->meta.job, false); + } - break; + break; - case JOB_RELOAD: - case JOB_RELOAD_OR_START: + case JOB_RELOAD: + case JOB_RELOAD_OR_START: + if (u->meta.job->state == JOB_RUNNING) { if (ns == UNIT_ACTIVE) job_finish_and_invalidate(u->meta.job, true); else if (ns != UNIT_ACTIVATING && ns != UNIT_ACTIVE_RELOADING) { unexpected = true; job_finish_and_invalidate(u->meta.job, false); } + } - break; + break; - case JOB_STOP: - case JOB_RESTART: - case JOB_TRY_RESTART: + case JOB_STOP: + case JOB_RESTART: + case JOB_TRY_RESTART: - if (ns == UNIT_INACTIVE) - job_finish_and_invalidate(u->meta.job, true); - else if (ns != UNIT_DEACTIVATING) { - unexpected = true; - job_finish_and_invalidate(u->meta.job, false); - } + if (ns == UNIT_INACTIVE) + job_finish_and_invalidate(u->meta.job, true); + else if (u->meta.job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) { + unexpected = true; + job_finish_and_invalidate(u->meta.job, false); + } - break; + break; - default: - assert_not_reached("Job type unknown"); - } + default: + assert_not_reached("Job type unknown"); } } @@ -1794,6 +1793,9 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds) { if ((r = UNIT_VTABLE(u)->serialize(u, f, fds)) < 0) return r; + if (u->meta.job) + unit_serialize_item(u, f, "job", job_type_to_string(u->meta.job->type)); + /* End marker */ fputc('\n', f); return 0; @@ -1860,6 +1862,17 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { } else v = l+k; + if (streq(l, "job")) { + JobType type; + + if ((type = job_type_from_string(v)) < 0) + log_debug("Failed to parse job type value %s", v); + else + u->meta.deserialized_job = type; + + continue; + } + if ((r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds)) < 0) return r; } @@ -1902,6 +1915,25 @@ int unit_add_node_link(Unit *u, const char *what, bool wants) { return 0; } +int unit_coldplug(Unit *u) { + int r; + + assert(u); + + if (UNIT_VTABLE(u)->coldplug) + if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0) + return r; + + if (u->meta.deserialized_job >= 0) { + if ((r = manager_add_job(u->meta.manager, u->meta.deserialized_job, u, JOB_FAIL, false, NULL)) < 0) + return r; + + u->meta.deserialized_job = _JOB_TYPE_INVALID; + } + + return 0; +} + static const char* const unit_type_table[_UNIT_TYPE_MAX] = { [UNIT_SERVICE] = "service", [UNIT_TIMER] = "timer",