chiark / gitweb /
core: add NOP jobs, job type collapsing
[elogind.git] / src / core / job.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <assert.h>
23 #include <errno.h>
24 #include <sys/timerfd.h>
25 #include <sys/epoll.h>
26
27 #include "set.h"
28 #include "unit.h"
29 #include "macro.h"
30 #include "strv.h"
31 #include "load-fragment.h"
32 #include "load-dropin.h"
33 #include "log.h"
34 #include "dbus-job.h"
35
36 JobBusClient* job_bus_client_new(DBusConnection *connection, const char *name) {
37         JobBusClient *cl;
38         size_t name_len;
39
40         name_len = strlen(name);
41         cl = malloc0(sizeof(JobBusClient) + name_len + 1);
42         if (!cl)
43                 return NULL;
44
45         cl->bus = connection;
46         memcpy(cl->name, name, name_len + 1);
47         return cl;
48 }
49
50 Job* job_new_raw(Unit *unit) {
51         Job *j;
52
53         /* used for deserialization */
54
55         assert(unit);
56
57         j = new0(Job, 1);
58         if (!j)
59                 return NULL;
60
61         j->manager = unit->manager;
62         j->unit = unit;
63         j->type = _JOB_TYPE_INVALID;
64         j->timer_watch.type = WATCH_INVALID;
65
66         return j;
67 }
68
69 Job* job_new(Unit *unit, JobType type) {
70         Job *j;
71
72         assert(type < _JOB_TYPE_MAX);
73
74         j = job_new_raw(unit);
75         if (!j)
76                 return NULL;
77
78         j->id = j->manager->current_job_id++;
79         j->type = type;
80
81         /* We don't link it here, that's what job_dependency() is for */
82
83         return j;
84 }
85
86 void job_free(Job *j) {
87         JobBusClient *cl;
88
89         assert(j);
90         assert(!j->installed);
91         assert(!j->transaction_prev);
92         assert(!j->transaction_next);
93         assert(!j->subject_list);
94         assert(!j->object_list);
95
96         if (j->in_run_queue)
97                 LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
98
99         if (j->in_dbus_queue)
100                 LIST_REMOVE(Job, dbus_queue, j->manager->dbus_job_queue, j);
101
102         if (j->timer_watch.type != WATCH_INVALID) {
103                 assert(j->timer_watch.type == WATCH_JOB_TIMER);
104                 assert(j->timer_watch.data.job == j);
105                 assert(j->timer_watch.fd >= 0);
106
107                 assert_se(epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_DEL, j->timer_watch.fd, NULL) >= 0);
108                 close_nointr_nofail(j->timer_watch.fd);
109         }
110
111         while ((cl = j->bus_client_list)) {
112                 LIST_REMOVE(JobBusClient, client, j->bus_client_list, cl);
113                 free(cl);
114         }
115         free(j);
116 }
117
118 void job_uninstall(Job *j) {
119         Job **pj;
120
121         assert(j->installed);
122
123         pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
124         assert(*pj == j);
125
126         /* Detach from next 'bigger' objects */
127
128         /* daemon-reload should be transparent to job observers */
129         if (j->manager->n_reloading <= 0)
130                 bus_job_send_removed_signal(j);
131
132         *pj = NULL;
133
134         unit_add_to_gc_queue(j->unit);
135
136         hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id));
137         j->installed = false;
138 }
139
140 static bool job_type_allows_late_merge(JobType t) {
141         /* Tells whether it is OK to merge a job of type 't' with an already
142          * running job.
143          * Reloads cannot be merged this way. Think of the sequence:
144          * 1. Reload of a daemon is in progress; the daemon has already loaded
145          *    its config file, but hasn't completed the reload operation yet.
146          * 2. Edit foo's config file.
147          * 3. Trigger another reload to have the daemon use the new config.
148          * Should the second reload job be merged into the first one, the daemon
149          * would not know about the new config.
150          * JOB_RESTART jobs on the other hand can be merged, because they get
151          * patched into JOB_START after stopping the unit. So if we see a
152          * JOB_RESTART running, it means the unit hasn't stopped yet and at
153          * this time the merge is still allowed. */
154         return t != JOB_RELOAD;
155 }
156
157 static void job_merge_into_installed(Job *j, Job *other) {
158         assert(j->installed);
159         assert(j->unit == other->unit);
160
161         if (j->type != JOB_NOP)
162                 job_type_merge_and_collapse(&j->type, other->type, j->unit);
163         else
164                 assert(other->type == JOB_NOP);
165
166         j->override = j->override || other->override;
167 }
168
169 Job* job_install(Job *j) {
170         Job **pj;
171         Job *uj;
172
173         assert(!j->installed);
174         assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
175
176         pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
177         uj = *pj;
178
179         if (uj) {
180                 if (j->type != JOB_NOP && job_type_is_conflicting(uj->type, j->type))
181                         job_finish_and_invalidate(uj, JOB_CANCELED, true);
182                 else {
183                         /* not conflicting, i.e. mergeable */
184
185                         if (j->type == JOB_NOP || uj->state == JOB_WAITING ||
186                             (job_type_allows_late_merge(j->type) && job_type_is_superset(uj->type, j->type))) {
187                                 job_merge_into_installed(uj, j);
188                                 log_debug("Merged into installed job %s/%s as %u",
189                                           uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id);
190                                 return uj;
191                         } else {
192                                 /* already running and not safe to merge into */
193                                 /* Patch uj to become a merged job and re-run it. */
194                                 /* XXX It should be safer to queue j to run after uj finishes, but it is
195                                  * not currently possible to have more than one installed job per unit. */
196                                 job_merge_into_installed(uj, j);
197                                 log_debug("Merged into running job, re-running: %s/%s as %u",
198                                           uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id);
199                                 uj->state = JOB_WAITING;
200                                 return uj;
201                         }
202                 }
203         }
204
205         /* Install the job */
206         *pj = j;
207         j->installed = true;
208         j->manager->n_installed_jobs ++;
209         log_debug("Installed new job %s/%s as %u", j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
210         return j;
211 }
212
213 int job_install_deserialized(Job *j) {
214         Job **pj;
215
216         assert(!j->installed);
217
218         if (j->type < 0 || j->type >= _JOB_TYPE_MAX_IN_TRANSACTION) {
219                 log_debug("Invalid job type %s in deserialization.", strna(job_type_to_string(j->type)));
220                 return -EINVAL;
221         }
222
223         pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
224
225         if (*pj) {
226                 log_debug("Unit %s already has a job installed. Not installing deserialized job.", j->unit->id);
227                 return -EEXIST;
228         }
229         *pj = j;
230         j->installed = true;
231         log_debug("Reinstalled deserialized job %s/%s as %u", j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
232         return 0;
233 }
234
235 JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts) {
236         JobDependency *l;
237
238         assert(object);
239
240         /* Adds a new job link, which encodes that the 'subject' job
241          * needs the 'object' job in some way. If 'subject' is NULL
242          * this means the 'anchor' job (i.e. the one the user
243          * explicitly asked for) is the requester. */
244
245         if (!(l = new0(JobDependency, 1)))
246                 return NULL;
247
248         l->subject = subject;
249         l->object = object;
250         l->matters = matters;
251         l->conflicts = conflicts;
252
253         if (subject)
254                 LIST_PREPEND(JobDependency, subject, subject->subject_list, l);
255
256         LIST_PREPEND(JobDependency, object, object->object_list, l);
257
258         return l;
259 }
260
261 void job_dependency_free(JobDependency *l) {
262         assert(l);
263
264         if (l->subject)
265                 LIST_REMOVE(JobDependency, subject, l->subject->subject_list, l);
266
267         LIST_REMOVE(JobDependency, object, l->object->object_list, l);
268
269         free(l);
270 }
271
272 void job_dump(Job *j, FILE*f, const char *prefix) {
273         assert(j);
274         assert(f);
275
276         if (!prefix)
277                 prefix = "";
278
279         fprintf(f,
280                 "%s-> Job %u:\n"
281                 "%s\tAction: %s -> %s\n"
282                 "%s\tState: %s\n"
283                 "%s\tForced: %s\n",
284                 prefix, j->id,
285                 prefix, j->unit->id, job_type_to_string(j->type),
286                 prefix, job_state_to_string(j->state),
287                 prefix, yes_no(j->override));
288 }
289
290 /*
291  * Merging is commutative, so imagine the matrix as symmetric. We store only
292  * its lower triangle to avoid duplication. We don't store the main diagonal,
293  * because A merged with A is simply A.
294  *
295  * If the resulting type is collapsed immediately afterwards (to get rid of
296  * the JOB_RELOAD_OR_START, which lies outside the lookup function's domain),
297  * the following properties hold:
298  *
299  * Merging is associative! A merged with B merged with C is the same as
300  * A merged with C merged with B.
301  *
302  * Mergeability is transitive! If A can be merged with B and B with C then
303  * A also with C.
304  *
305  * Also, if A merged with B cannot be merged with C, then either A or B cannot
306  * be merged with C either.
307  */
308 static const JobType job_merging_table[] = {
309 /* What \ With       *  JOB_START         JOB_VERIFY_ACTIVE  JOB_STOP JOB_RELOAD */
310 /*********************************************************************************/
311 /*JOB_START          */
312 /*JOB_VERIFY_ACTIVE  */ JOB_START,
313 /*JOB_STOP           */ -1,                  -1,
314 /*JOB_RELOAD         */ JOB_RELOAD_OR_START, JOB_RELOAD,          -1,
315 /*JOB_RESTART        */ JOB_RESTART,         JOB_RESTART,         -1, JOB_RESTART,
316 };
317
318 JobType job_type_lookup_merge(JobType a, JobType b) {
319         assert_cc(ELEMENTSOF(job_merging_table) == _JOB_TYPE_MAX_MERGING * (_JOB_TYPE_MAX_MERGING - 1) / 2);
320         assert(a >= 0 && a < _JOB_TYPE_MAX_MERGING);
321         assert(b >= 0 && b < _JOB_TYPE_MAX_MERGING);
322
323         if (a == b)
324                 return a;
325
326         if (a < b) {
327                 JobType tmp = a;
328                 a = b;
329                 b = tmp;
330         }
331
332         return job_merging_table[(a - 1) * a / 2 + b];
333 }
334
335 bool job_type_is_redundant(JobType a, UnitActiveState b) {
336         switch (a) {
337
338         case JOB_START:
339                 return
340                         b == UNIT_ACTIVE ||
341                         b == UNIT_RELOADING;
342
343         case JOB_STOP:
344                 return
345                         b == UNIT_INACTIVE ||
346                         b == UNIT_FAILED;
347
348         case JOB_VERIFY_ACTIVE:
349                 return
350                         b == UNIT_ACTIVE ||
351                         b == UNIT_RELOADING;
352
353         case JOB_RELOAD:
354                 return
355                         b == UNIT_RELOADING;
356
357         case JOB_RESTART:
358                 return
359                         b == UNIT_ACTIVATING;
360
361         default:
362                 assert_not_reached("Invalid job type");
363         }
364 }
365
366 void job_type_collapse(JobType *t, Unit *u) {
367         UnitActiveState s;
368
369         switch (*t) {
370
371         case JOB_TRY_RESTART:
372                 s = unit_active_state(u);
373                 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
374                         *t = JOB_NOP;
375                 else
376                         *t = JOB_RESTART;
377                 break;
378
379         case JOB_RELOAD_OR_START:
380                 s = unit_active_state(u);
381                 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
382                         *t = JOB_START;
383                 else
384                         *t = JOB_RELOAD;
385                 break;
386
387         default:
388                 ;
389         }
390 }
391
392 int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u) {
393         JobType t = job_type_lookup_merge(*a, b);
394         if (t < 0)
395                 return -EEXIST;
396         *a = t;
397         job_type_collapse(a, u);
398         return 0;
399 }
400
401 bool job_is_runnable(Job *j) {
402         Iterator i;
403         Unit *other;
404
405         assert(j);
406         assert(j->installed);
407
408         /* Checks whether there is any job running for the units this
409          * job needs to be running after (in the case of a 'positive'
410          * job type) or before (in the case of a 'negative' job
411          * type. */
412
413         /* First check if there is an override */
414         if (j->ignore_order)
415                 return true;
416
417         if (j->type == JOB_NOP)
418                 return true;
419
420         if (j->type == JOB_START ||
421             j->type == JOB_VERIFY_ACTIVE ||
422             j->type == JOB_RELOAD) {
423
424                 /* Immediate result is that the job is or might be
425                  * started. In this case lets wait for the
426                  * dependencies, regardless whether they are
427                  * starting or stopping something. */
428
429                 SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i)
430                         if (other->job)
431                                 return false;
432         }
433
434         /* Also, if something else is being stopped and we should
435          * change state after it, then lets wait. */
436
437         SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i)
438                 if (other->job &&
439                     (other->job->type == JOB_STOP ||
440                      other->job->type == JOB_RESTART))
441                         return false;
442
443         /* This means that for a service a and a service b where b
444          * shall be started after a:
445          *
446          *  start a + start b â†’ 1st step start a, 2nd step start b
447          *  start a + stop b  â†’ 1st step stop b,  2nd step start a
448          *  stop a  + start b â†’ 1st step stop a,  2nd step start b
449          *  stop a  + stop b  â†’ 1st step stop b,  2nd step stop a
450          *
451          *  This has the side effect that restarts are properly
452          *  synchronized too. */
453
454         return true;
455 }
456
457 static void job_change_type(Job *j, JobType newtype) {
458         log_debug("Converting job %s/%s -> %s/%s",
459                   j->unit->id, job_type_to_string(j->type),
460                   j->unit->id, job_type_to_string(newtype));
461
462         j->type = newtype;
463 }
464
465 int job_run_and_invalidate(Job *j) {
466         int r;
467         uint32_t id;
468         Manager *m;
469
470         assert(j);
471         assert(j->installed);
472         assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
473
474         if (j->in_run_queue) {
475                 LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
476                 j->in_run_queue = false;
477         }
478
479         if (j->state != JOB_WAITING)
480                 return 0;
481
482         if (!job_is_runnable(j))
483                 return -EAGAIN;
484
485         j->state = JOB_RUNNING;
486         job_add_to_dbus_queue(j);
487
488         /* While we execute this operation the job might go away (for
489          * example: because it is replaced by a new, conflicting
490          * job.) To make sure we don't access a freed job later on we
491          * store the id here, so that we can verify the job is still
492          * valid. */
493         id = j->id;
494         m = j->manager;
495
496         switch (j->type) {
497
498                 case JOB_START:
499                         r = unit_start(j->unit);
500
501                         /* If this unit cannot be started, then simply wait */
502                         if (r == -EBADR)
503                                 r = 0;
504                         break;
505
506                 case JOB_VERIFY_ACTIVE: {
507                         UnitActiveState t = unit_active_state(j->unit);
508                         if (UNIT_IS_ACTIVE_OR_RELOADING(t))
509                                 r = -EALREADY;
510                         else if (t == UNIT_ACTIVATING)
511                                 r = -EAGAIN;
512                         else
513                                 r = -ENOEXEC;
514                         break;
515                 }
516
517                 case JOB_STOP:
518                 case JOB_RESTART:
519                         r = unit_stop(j->unit);
520
521                         /* If this unit cannot stopped, then simply wait. */
522                         if (r == -EBADR)
523                                 r = 0;
524                         break;
525
526                 case JOB_RELOAD:
527                         r = unit_reload(j->unit);
528                         break;
529
530                 case JOB_NOP:
531                         r = -EALREADY;
532                         break;
533
534                 default:
535                         assert_not_reached("Unknown job type");
536         }
537
538         j = manager_get_job(m, id);
539         if (j) {
540                 if (r == -EALREADY)
541                         r = job_finish_and_invalidate(j, JOB_DONE, true);
542                 else if (r == -ENOEXEC)
543                         r = job_finish_and_invalidate(j, JOB_SKIPPED, true);
544                 else if (r == -EAGAIN)
545                         j->state = JOB_WAITING;
546                 else if (r < 0)
547                         r = job_finish_and_invalidate(j, JOB_FAILED, true);
548         }
549
550         return r;
551 }
552
553 static void job_print_status_message(Unit *u, JobType t, JobResult result) {
554         assert(u);
555
556         if (t == JOB_START) {
557
558                 switch (result) {
559
560                 case JOB_DONE:
561                         if (u->condition_result)
562                                 unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON "  OK  " ANSI_HIGHLIGHT_OFF, "Started %s.", unit_description(u));
563                         break;
564
565                 case JOB_FAILED:
566                         unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, "Failed to start %s.", unit_description(u));
567                         unit_status_printf(u, NULL, "See 'systemctl status %s' for details.", u->id);
568                         break;
569
570                 case JOB_DEPENDENCY:
571                         unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " ABORT" ANSI_HIGHLIGHT_OFF, "Dependency failed. Aborted start of %s.", unit_description(u));
572                         break;
573
574                 case JOB_TIMEOUT:
575                         unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, "Timed out starting %s.", unit_description(u));
576                         break;
577
578                 default:
579                         ;
580                 }
581
582         } else if (t == JOB_STOP) {
583
584                 switch (result) {
585
586                 case JOB_TIMEOUT:
587                         unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, "Timed out stopping %s.", unit_description(u));
588                         break;
589
590                 case JOB_DONE:
591                 case JOB_FAILED:
592                         unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON "  OK  " ANSI_HIGHLIGHT_OFF, "Stopped %s.", unit_description(u));
593                         break;
594
595                 default:
596                         ;
597                 }
598         }
599 }
600
601 int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
602         Unit *u;
603         Unit *other;
604         JobType t;
605         Iterator i;
606
607         assert(j);
608         assert(j->installed);
609         assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
610
611         job_add_to_dbus_queue(j);
612
613         /* Patch restart jobs so that they become normal start jobs */
614         if (result == JOB_DONE && j->type == JOB_RESTART) {
615
616                 job_change_type(j, JOB_START);
617                 j->state = JOB_WAITING;
618
619                 job_add_to_run_queue(j);
620
621                 u = j->unit;
622                 goto finish;
623         }
624
625         j->result = result;
626
627         log_debug("Job %s/%s finished, result=%s", j->unit->id, job_type_to_string(j->type), job_result_to_string(result));
628
629         if (result == JOB_FAILED)
630                 j->manager->n_failed_jobs ++;
631
632         u = j->unit;
633         t = j->type;
634         job_uninstall(j);
635         job_free(j);
636
637         job_print_status_message(u, t, result);
638
639         /* Fail depending jobs on failure */
640         if (result != JOB_DONE && recursive) {
641
642                 if (t == JOB_START ||
643                     t == JOB_VERIFY_ACTIVE) {
644
645                         SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
646                                 if (other->job &&
647                                     (other->job->type == JOB_START ||
648                                      other->job->type == JOB_VERIFY_ACTIVE))
649                                         job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
650
651                         SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
652                                 if (other->job &&
653                                     (other->job->type == JOB_START ||
654                                      other->job->type == JOB_VERIFY_ACTIVE))
655                                         job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
656
657                         SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
658                                 if (other->job &&
659                                     !other->job->override &&
660                                     (other->job->type == JOB_START ||
661                                      other->job->type == JOB_VERIFY_ACTIVE))
662                                         job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
663
664                 } else if (t == JOB_STOP) {
665
666                         SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
667                                 if (other->job &&
668                                     (other->job->type == JOB_START ||
669                                      other->job->type == JOB_VERIFY_ACTIVE))
670                                         job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
671                 }
672         }
673
674         /* Trigger OnFailure dependencies that are not generated by
675          * the unit itself. We don't tread JOB_CANCELED as failure in
676          * this context. And JOB_FAILURE is already handled by the
677          * unit itself. */
678         if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) {
679                 log_notice("Job %s/%s failed with result '%s'.",
680                            u->id,
681                            job_type_to_string(t),
682                            job_result_to_string(result));
683
684                 unit_trigger_on_failure(u);
685         }
686
687 finish:
688         /* Try to start the next jobs that can be started */
689         SET_FOREACH(other, u->dependencies[UNIT_AFTER], i)
690                 if (other->job)
691                         job_add_to_run_queue(other->job);
692         SET_FOREACH(other, u->dependencies[UNIT_BEFORE], i)
693                 if (other->job)
694                         job_add_to_run_queue(other->job);
695
696         manager_check_finished(u->manager);
697
698         return 0;
699 }
700
701 int job_start_timer(Job *j) {
702         struct itimerspec its;
703         struct epoll_event ev;
704         int fd, r;
705         assert(j);
706
707         if (j->unit->job_timeout <= 0 ||
708             j->timer_watch.type == WATCH_JOB_TIMER)
709                 return 0;
710
711         assert(j->timer_watch.type == WATCH_INVALID);
712
713         if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) {
714                 r = -errno;
715                 goto fail;
716         }
717
718         zero(its);
719         timespec_store(&its.it_value, j->unit->job_timeout);
720
721         if (timerfd_settime(fd, 0, &its, NULL) < 0) {
722                 r = -errno;
723                 goto fail;
724         }
725
726         zero(ev);
727         ev.data.ptr = &j->timer_watch;
728         ev.events = EPOLLIN;
729
730         if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
731                 r = -errno;
732                 goto fail;
733         }
734
735         j->timer_watch.type = WATCH_JOB_TIMER;
736         j->timer_watch.fd = fd;
737         j->timer_watch.data.job = j;
738
739         return 0;
740
741 fail:
742         if (fd >= 0)
743                 close_nointr_nofail(fd);
744
745         return r;
746 }
747
748 void job_add_to_run_queue(Job *j) {
749         assert(j);
750         assert(j->installed);
751
752         if (j->in_run_queue)
753                 return;
754
755         LIST_PREPEND(Job, run_queue, j->manager->run_queue, j);
756         j->in_run_queue = true;
757 }
758
759 void job_add_to_dbus_queue(Job *j) {
760         assert(j);
761         assert(j->installed);
762
763         if (j->in_dbus_queue)
764                 return;
765
766         /* We don't check if anybody is subscribed here, since this
767          * job might just have been created and not yet assigned to a
768          * connection/client. */
769
770         LIST_PREPEND(Job, dbus_queue, j->manager->dbus_job_queue, j);
771         j->in_dbus_queue = true;
772 }
773
774 char *job_dbus_path(Job *j) {
775         char *p;
776
777         assert(j);
778
779         if (asprintf(&p, "/org/freedesktop/systemd1/job/%lu", (unsigned long) j->id) < 0)
780                 return NULL;
781
782         return p;
783 }
784
785 void job_timer_event(Job *j, uint64_t n_elapsed, Watch *w) {
786         assert(j);
787         assert(w == &j->timer_watch);
788
789         log_warning("Job %s/%s timed out.", j->unit->id, job_type_to_string(j->type));
790         job_finish_and_invalidate(j, JOB_TIMEOUT, true);
791 }
792
793 int job_serialize(Job *j, FILE *f, FDSet *fds) {
794         fprintf(f, "job-id=%u\n", j->id);
795         fprintf(f, "job-type=%s\n", job_type_to_string(j->type));
796         fprintf(f, "job-state=%s\n", job_state_to_string(j->state));
797         fprintf(f, "job-override=%s\n", yes_no(j->override));
798         fprintf(f, "job-sent-dbus-new-signal=%s\n", yes_no(j->sent_dbus_new_signal));
799         fprintf(f, "job-ignore-order=%s\n", yes_no(j->ignore_order));
800         /* Cannot save bus clients. Just note the fact that we're losing
801          * them. job_send_message() will fallback to broadcasting. */
802         fprintf(f, "job-forgot-bus-clients=%s\n",
803                 yes_no(j->forgot_bus_clients || j->bus_client_list));
804         if (j->timer_watch.type == WATCH_JOB_TIMER) {
805                 int copy = fdset_put_dup(fds, j->timer_watch.fd);
806                 if (copy < 0)
807                         return copy;
808                 fprintf(f, "job-timer-watch-fd=%d\n", copy);
809         }
810
811         /* End marker */
812         fputc('\n', f);
813         return 0;
814 }
815
816 int job_deserialize(Job *j, FILE *f, FDSet *fds) {
817         for (;;) {
818                 char line[LINE_MAX], *l, *v;
819                 size_t k;
820
821                 if (!fgets(line, sizeof(line), f)) {
822                         if (feof(f))
823                                 return 0;
824                         return -errno;
825                 }
826
827                 char_array_0(line);
828                 l = strstrip(line);
829
830                 /* End marker */
831                 if (l[0] == 0)
832                         return 0;
833
834                 k = strcspn(l, "=");
835
836                 if (l[k] == '=') {
837                         l[k] = 0;
838                         v = l+k+1;
839                 } else
840                         v = l+k;
841
842                 if (streq(l, "job-id")) {
843                         if (safe_atou32(v, &j->id) < 0)
844                                 log_debug("Failed to parse job id value %s", v);
845                 } else if (streq(l, "job-type")) {
846                         JobType t = job_type_from_string(v);
847                         if (t < 0)
848                                 log_debug("Failed to parse job type %s", v);
849                         else if (t >= _JOB_TYPE_MAX_IN_TRANSACTION)
850                                 log_debug("Cannot deserialize job of type %s", v);
851                         else
852                                 j->type = t;
853                 } else if (streq(l, "job-state")) {
854                         JobState s = job_state_from_string(v);
855                         if (s < 0)
856                                 log_debug("Failed to parse job state %s", v);
857                         else
858                                 j->state = s;
859                 } else if (streq(l, "job-override")) {
860                         int b = parse_boolean(v);
861                         if (b < 0)
862                                 log_debug("Failed to parse job override flag %s", v);
863                         else
864                                 j->override = j->override || b;
865                 } else if (streq(l, "job-sent-dbus-new-signal")) {
866                         int b = parse_boolean(v);
867                         if (b < 0)
868                                 log_debug("Failed to parse job sent_dbus_new_signal flag %s", v);
869                         else
870                                 j->sent_dbus_new_signal = j->sent_dbus_new_signal || b;
871                 } else if (streq(l, "job-ignore-order")) {
872                         int b = parse_boolean(v);
873                         if (b < 0)
874                                 log_debug("Failed to parse job ignore_order flag %s", v);
875                         else
876                                 j->ignore_order = j->ignore_order || b;
877                 } else if (streq(l, "job-forgot-bus-clients")) {
878                         int b = parse_boolean(v);
879                         if (b < 0)
880                                 log_debug("Failed to parse job forgot_bus_clients flag %s", v);
881                         else
882                                 j->forgot_bus_clients = j->forgot_bus_clients || b;
883                 } else if (streq(l, "job-timer-watch-fd")) {
884                         int fd;
885                         if (safe_atoi(v, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
886                                 log_debug("Failed to parse job-timer-watch-fd value %s", v);
887                         else {
888                                 if (j->timer_watch.type == WATCH_JOB_TIMER)
889                                         close_nointr_nofail(j->timer_watch.fd);
890
891                                 j->timer_watch.type = WATCH_JOB_TIMER;
892                                 j->timer_watch.fd = fdset_remove(fds, fd);
893                                 j->timer_watch.data.job = j;
894                         }
895                 }
896         }
897 }
898
899 int job_coldplug(Job *j) {
900         struct epoll_event ev;
901
902         if (j->timer_watch.type != WATCH_JOB_TIMER)
903                 return 0;
904
905         zero(ev);
906         ev.data.ptr = &j->timer_watch;
907         ev.events = EPOLLIN;
908
909         if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, j->timer_watch.fd, &ev) < 0)
910                 return -errno;
911
912         return 0;
913 }
914
915 static const char* const job_state_table[_JOB_STATE_MAX] = {
916         [JOB_WAITING] = "waiting",
917         [JOB_RUNNING] = "running"
918 };
919
920 DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
921
922 static const char* const job_type_table[_JOB_TYPE_MAX] = {
923         [JOB_START] = "start",
924         [JOB_VERIFY_ACTIVE] = "verify-active",
925         [JOB_STOP] = "stop",
926         [JOB_RELOAD] = "reload",
927         [JOB_RELOAD_OR_START] = "reload-or-start",
928         [JOB_RESTART] = "restart",
929         [JOB_TRY_RESTART] = "try-restart",
930         [JOB_NOP] = "nop",
931 };
932
933 DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
934
935 static const char* const job_mode_table[_JOB_MODE_MAX] = {
936         [JOB_FAIL] = "fail",
937         [JOB_REPLACE] = "replace",
938         [JOB_ISOLATE] = "isolate",
939         [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
940         [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements"
941 };
942
943 DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
944
945 static const char* const job_result_table[_JOB_RESULT_MAX] = {
946         [JOB_DONE] = "done",
947         [JOB_CANCELED] = "canceled",
948         [JOB_TIMEOUT] = "timeout",
949         [JOB_FAILED] = "failed",
950         [JOB_DEPENDENCY] = "dependency",
951         [JOB_SKIPPED] = "skipped"
952 };
953
954 DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);