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