summaryrefslogtreecommitdiff
path: root/src/core/unit.c
diff options
context:
space:
mode:
authorMichal Schmidt <mschmidt@redhat.com>2012-04-23 01:24:04 +0200
committerMichal Schmidt <mschmidt@redhat.com>2012-04-24 01:54:15 +0200
commit39a18c60d07319ebfcfd476556729c2cadd616d6 (patch)
treeb29036c82f9ae41e1366fea752f9e74ab0a1b29e /src/core/unit.c
parent1b9cea0caa85dce6d9f117638a296b141c49a8fd (diff)
job: serialize jobs properly
Jobs were not preserved correctly over a daemon-reload operation. A systemctl process waiting for a job completion received a job removal signal. The job itself changed its id. The job timeout started ticking all over again. This fixes the deficiencies.
Diffstat (limited to 'src/core/unit.c')
-rw-r--r--src/core/unit.c47
1 files changed, 37 insertions, 10 deletions
diff --git a/src/core/unit.c b/src/core/unit.c
index ed3f176393..1f8d52b3ca 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -2288,8 +2288,10 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds) {
if ((r = UNIT_VTABLE(u)->serialize(u, f, fds)) < 0)
return r;
- if (u->job)
- unit_serialize_item(u, f, "job", job_type_to_string(u->job->type));
+ if (u->job) {
+ fprintf(f, "job\n");
+ job_serialize(u->job, f, fds);
+ }
dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp);
dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp);
@@ -2368,13 +2370,32 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
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->deserialized_job = type;
+ if (v[0] == '\0') {
+ /* new-style serialized job */
+ Job *j = job_new_raw(u);
+ if (!j)
+ return -ENOMEM;
+
+ r = job_deserialize(j, f, fds);
+ if (r < 0) {
+ job_free(j);
+ return r;
+ }
+ job_install_deserialized(j);
+ r = hashmap_put(u->manager->jobs, UINT32_TO_PTR(j->id), j);
+ if (r < 0) {
+ job_free(j);
+ return r;
+ }
+ } else {
+ /* legacy */
+ JobType type = job_type_from_string(v);
+ if (type < 0)
+ log_debug("Failed to parse job type value %s", v);
+ else
+ u->deserialized_job = type;
+ }
continue;
} else if (streq(l, "inactive-exit-timestamp")) {
dual_timestamp_deserialize(v, &u->inactive_exit_timestamp);
@@ -2450,8 +2471,14 @@ int unit_coldplug(Unit *u) {
if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0)
return r;
- if (u->deserialized_job >= 0) {
- if ((r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL)) < 0)
+ if (u->job) {
+ r = job_coldplug(u->job);
+ if (r < 0)
+ return r;
+ } else if (u->deserialized_job >= 0) {
+ /* legacy */
+ r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL);
+ if (r < 0)
return r;
u->deserialized_job = _JOB_TYPE_INVALID;