chiark / gitweb /
unit: unit type dependent status messages
[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         assert(j->in_run_queue);
474
475         LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
476         j->in_run_queue = false;
477
478         if (j->state != JOB_WAITING)
479                 return 0;
480
481         if (!job_is_runnable(j))
482                 return -EAGAIN;
483
484         j->state = JOB_RUNNING;
485         job_add_to_dbus_queue(j);
486
487         /* While we execute this operation the job might go away (for
488          * example: because it is replaced by a new, conflicting
489          * job.) To make sure we don't access a freed job later on we
490          * store the id here, so that we can verify the job is still
491          * valid. */
492         id = j->id;
493         m = j->manager;
494
495         switch (j->type) {
496
497                 case JOB_START:
498                         r = unit_start(j->unit);
499
500                         /* If this unit cannot be started, then simply wait */
501                         if (r == -EBADR)
502                                 r = 0;
503                         break;
504
505                 case JOB_VERIFY_ACTIVE: {
506                         UnitActiveState t = unit_active_state(j->unit);
507                         if (UNIT_IS_ACTIVE_OR_RELOADING(t))
508                                 r = -EALREADY;
509                         else if (t == UNIT_ACTIVATING)
510                                 r = -EAGAIN;
511                         else
512                                 r = -ENOEXEC;
513                         break;
514                 }
515
516                 case JOB_STOP:
517                 case JOB_RESTART:
518                         r = unit_stop(j->unit);
519
520                         /* If this unit cannot stopped, then simply wait. */
521                         if (r == -EBADR)
522                                 r = 0;
523                         break;
524
525                 case JOB_RELOAD:
526                         r = unit_reload(j->unit);
527                         break;
528
529                 case JOB_NOP:
530                         r = -EALREADY;
531                         break;
532
533                 default:
534                         assert_not_reached("Unknown job type");
535         }
536
537         j = manager_get_job(m, id);
538         if (j) {
539                 if (r == -EALREADY)
540                         r = job_finish_and_invalidate(j, JOB_DONE, true);
541                 else if (r == -ENOEXEC)
542                         r = job_finish_and_invalidate(j, JOB_SKIPPED, true);
543                 else if (r == -EAGAIN)
544                         j->state = JOB_WAITING;
545                 else if (r < 0)
546                         r = job_finish_and_invalidate(j, JOB_FAILED, true);
547         }
548
549         return r;
550 }
551
552 static void job_print_status_message(Unit *u, JobType t, JobResult result) {
553         const UnitStatusMessageFormats *format_table;
554         const char *format;
555
556         format_table = &UNIT_VTABLE(u)->status_message_formats;
557         if (!format_table)
558                 return;
559
560         if (t == JOB_START) {
561
562                 format = format_table->finished_start_job[result];
563                 if (!format)
564                         return;
565
566                 switch (result) {
567
568                 case JOB_DONE:
569                         if (u->condition_result)
570                                 unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON "  OK  " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
571                         break;
572
573                 case JOB_FAILED:
574                         unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, format, unit_description(u));
575                         unit_status_printf(u, "", "See 'systemctl status %s' for details.", u->id);
576                         break;
577
578                 case JOB_DEPENDENCY:
579                         unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "DEPEND" ANSI_HIGHLIGHT_OFF, format, unit_description(u));
580                         break;
581
582                 case JOB_TIMEOUT:
583                         unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
584                         break;
585
586                 default:
587                         ;
588                 }
589
590         } else if (t == JOB_STOP) {
591
592                 format = format_table->finished_stop_job[result];
593                 if (!format)
594                         return;
595
596                 switch (result) {
597
598                 case JOB_TIMEOUT:
599                         unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
600                         break;
601
602                 case JOB_DONE:
603                 case JOB_FAILED:
604                         unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON "  OK  " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
605                         break;
606
607                 default:
608                         ;
609                 }
610         }
611 }
612
613 int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
614         Unit *u;
615         Unit *other;
616         JobType t;
617         Iterator i;
618
619         assert(j);
620         assert(j->installed);
621         assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
622
623         u = j->unit;
624         t = j->type;
625
626         j->result = result;
627
628         log_debug("Job %s/%s finished, result=%s", u->id, job_type_to_string(t), job_result_to_string(result));
629
630         job_print_status_message(u, t, result);
631
632         job_add_to_dbus_queue(j);
633
634         /* Patch restart jobs so that they become normal start jobs */
635         if (result == JOB_DONE && t == JOB_RESTART) {
636
637                 job_change_type(j, JOB_START);
638                 j->state = JOB_WAITING;
639
640                 job_add_to_run_queue(j);
641
642                 goto finish;
643         }
644
645         if (result == JOB_FAILED)
646                 j->manager->n_failed_jobs ++;
647
648         job_uninstall(j);
649         job_free(j);
650
651         /* Fail depending jobs on failure */
652         if (result != JOB_DONE && recursive) {
653
654                 if (t == JOB_START ||
655                     t == JOB_VERIFY_ACTIVE) {
656
657                         SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
658                                 if (other->job &&
659                                     (other->job->type == JOB_START ||
660                                      other->job->type == JOB_VERIFY_ACTIVE))
661                                         job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
662
663                         SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
664                                 if (other->job &&
665                                     (other->job->type == JOB_START ||
666                                      other->job->type == JOB_VERIFY_ACTIVE))
667                                         job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
668
669                         SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
670                                 if (other->job &&
671                                     !other->job->override &&
672                                     (other->job->type == JOB_START ||
673                                      other->job->type == JOB_VERIFY_ACTIVE))
674                                         job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
675
676                 } else if (t == JOB_STOP) {
677
678                         SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
679                                 if (other->job &&
680                                     (other->job->type == JOB_START ||
681                                      other->job->type == JOB_VERIFY_ACTIVE))
682                                         job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
683                 }
684         }
685
686         /* Trigger OnFailure dependencies that are not generated by
687          * the unit itself. We don't tread JOB_CANCELED as failure in
688          * this context. And JOB_FAILURE is already handled by the
689          * unit itself. */
690         if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) {
691                 log_notice("Job %s/%s failed with result '%s'.",
692                            u->id,
693                            job_type_to_string(t),
694                            job_result_to_string(result));
695
696                 unit_trigger_on_failure(u);
697         }
698
699 finish:
700         /* Try to start the next jobs that can be started */
701         SET_FOREACH(other, u->dependencies[UNIT_AFTER], i)
702                 if (other->job)
703                         job_add_to_run_queue(other->job);
704         SET_FOREACH(other, u->dependencies[UNIT_BEFORE], i)
705                 if (other->job)
706                         job_add_to_run_queue(other->job);
707
708         manager_check_finished(u->manager);
709
710         return 0;
711 }
712
713 int job_start_timer(Job *j) {
714         struct itimerspec its;
715         struct epoll_event ev;
716         int fd, r;
717         assert(j);
718
719         if (j->unit->job_timeout <= 0 ||
720             j->timer_watch.type == WATCH_JOB_TIMER)
721                 return 0;
722
723         assert(j->timer_watch.type == WATCH_INVALID);
724
725         if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) {
726                 r = -errno;
727                 goto fail;
728         }
729
730         zero(its);
731         timespec_store(&its.it_value, j->unit->job_timeout);
732
733         if (timerfd_settime(fd, 0, &its, NULL) < 0) {
734                 r = -errno;
735                 goto fail;
736         }
737
738         zero(ev);
739         ev.data.ptr = &j->timer_watch;
740         ev.events = EPOLLIN;
741
742         if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
743                 r = -errno;
744                 goto fail;
745         }
746
747         j->timer_watch.type = WATCH_JOB_TIMER;
748         j->timer_watch.fd = fd;
749         j->timer_watch.data.job = j;
750
751         return 0;
752
753 fail:
754         if (fd >= 0)
755                 close_nointr_nofail(fd);
756
757         return r;
758 }
759
760 void job_add_to_run_queue(Job *j) {
761         assert(j);
762         assert(j->installed);
763
764         if (j->in_run_queue)
765                 return;
766
767         LIST_PREPEND(Job, run_queue, j->manager->run_queue, j);
768         j->in_run_queue = true;
769 }
770
771 void job_add_to_dbus_queue(Job *j) {
772         assert(j);
773         assert(j->installed);
774
775         if (j->in_dbus_queue)
776                 return;
777
778         /* We don't check if anybody is subscribed here, since this
779          * job might just have been created and not yet assigned to a
780          * connection/client. */
781
782         LIST_PREPEND(Job, dbus_queue, j->manager->dbus_job_queue, j);
783         j->in_dbus_queue = true;
784 }
785
786 char *job_dbus_path(Job *j) {
787         char *p;
788
789         assert(j);
790
791         if (asprintf(&p, "/org/freedesktop/systemd1/job/%lu", (unsigned long) j->id) < 0)
792                 return NULL;
793
794         return p;
795 }
796
797 void job_timer_event(Job *j, uint64_t n_elapsed, Watch *w) {
798         assert(j);
799         assert(w == &j->timer_watch);
800
801         log_warning("Job %s/%s timed out.", j->unit->id, job_type_to_string(j->type));
802         job_finish_and_invalidate(j, JOB_TIMEOUT, true);
803 }
804
805 int job_serialize(Job *j, FILE *f, FDSet *fds) {
806         fprintf(f, "job-id=%u\n", j->id);
807         fprintf(f, "job-type=%s\n", job_type_to_string(j->type));
808         fprintf(f, "job-state=%s\n", job_state_to_string(j->state));
809         fprintf(f, "job-override=%s\n", yes_no(j->override));
810         fprintf(f, "job-sent-dbus-new-signal=%s\n", yes_no(j->sent_dbus_new_signal));
811         fprintf(f, "job-ignore-order=%s\n", yes_no(j->ignore_order));
812         /* Cannot save bus clients. Just note the fact that we're losing
813          * them. job_send_message() will fallback to broadcasting. */
814         fprintf(f, "job-forgot-bus-clients=%s\n",
815                 yes_no(j->forgot_bus_clients || j->bus_client_list));
816         if (j->timer_watch.type == WATCH_JOB_TIMER) {
817                 int copy = fdset_put_dup(fds, j->timer_watch.fd);
818                 if (copy < 0)
819                         return copy;
820                 fprintf(f, "job-timer-watch-fd=%d\n", copy);
821         }
822
823         /* End marker */
824         fputc('\n', f);
825         return 0;
826 }
827
828 int job_deserialize(Job *j, FILE *f, FDSet *fds) {
829         for (;;) {
830                 char line[LINE_MAX], *l, *v;
831                 size_t k;
832
833                 if (!fgets(line, sizeof(line), f)) {
834                         if (feof(f))
835                                 return 0;
836                         return -errno;
837                 }
838
839                 char_array_0(line);
840                 l = strstrip(line);
841
842                 /* End marker */
843                 if (l[0] == 0)
844                         return 0;
845
846                 k = strcspn(l, "=");
847
848                 if (l[k] == '=') {
849                         l[k] = 0;
850                         v = l+k+1;
851                 } else
852                         v = l+k;
853
854                 if (streq(l, "job-id")) {
855                         if (safe_atou32(v, &j->id) < 0)
856                                 log_debug("Failed to parse job id value %s", v);
857                 } else if (streq(l, "job-type")) {
858                         JobType t = job_type_from_string(v);
859                         if (t < 0)
860                                 log_debug("Failed to parse job type %s", v);
861                         else if (t >= _JOB_TYPE_MAX_IN_TRANSACTION)
862                                 log_debug("Cannot deserialize job of type %s", v);
863                         else
864                                 j->type = t;
865                 } else if (streq(l, "job-state")) {
866                         JobState s = job_state_from_string(v);
867                         if (s < 0)
868                                 log_debug("Failed to parse job state %s", v);
869                         else
870                                 j->state = s;
871                 } else if (streq(l, "job-override")) {
872                         int b = parse_boolean(v);
873                         if (b < 0)
874                                 log_debug("Failed to parse job override flag %s", v);
875                         else
876                                 j->override = j->override || b;
877                 } else if (streq(l, "job-sent-dbus-new-signal")) {
878                         int b = parse_boolean(v);
879                         if (b < 0)
880                                 log_debug("Failed to parse job sent_dbus_new_signal flag %s", v);
881                         else
882                                 j->sent_dbus_new_signal = j->sent_dbus_new_signal || b;
883                 } else if (streq(l, "job-ignore-order")) {
884                         int b = parse_boolean(v);
885                         if (b < 0)
886                                 log_debug("Failed to parse job ignore_order flag %s", v);
887                         else
888                                 j->ignore_order = j->ignore_order || b;
889                 } else if (streq(l, "job-forgot-bus-clients")) {
890                         int b = parse_boolean(v);
891                         if (b < 0)
892                                 log_debug("Failed to parse job forgot_bus_clients flag %s", v);
893                         else
894                                 j->forgot_bus_clients = j->forgot_bus_clients || b;
895                 } else if (streq(l, "job-timer-watch-fd")) {
896                         int fd;
897                         if (safe_atoi(v, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
898                                 log_debug("Failed to parse job-timer-watch-fd value %s", v);
899                         else {
900                                 if (j->timer_watch.type == WATCH_JOB_TIMER)
901                                         close_nointr_nofail(j->timer_watch.fd);
902
903                                 j->timer_watch.type = WATCH_JOB_TIMER;
904                                 j->timer_watch.fd = fdset_remove(fds, fd);
905                                 j->timer_watch.data.job = j;
906                         }
907                 }
908         }
909 }
910
911 int job_coldplug(Job *j) {
912         struct epoll_event ev;
913
914         if (j->timer_watch.type != WATCH_JOB_TIMER)
915                 return 0;
916
917         zero(ev);
918         ev.data.ptr = &j->timer_watch;
919         ev.events = EPOLLIN;
920
921         if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, j->timer_watch.fd, &ev) < 0)
922                 return -errno;
923
924         return 0;
925 }
926
927 static const char* const job_state_table[_JOB_STATE_MAX] = {
928         [JOB_WAITING] = "waiting",
929         [JOB_RUNNING] = "running"
930 };
931
932 DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
933
934 static const char* const job_type_table[_JOB_TYPE_MAX] = {
935         [JOB_START] = "start",
936         [JOB_VERIFY_ACTIVE] = "verify-active",
937         [JOB_STOP] = "stop",
938         [JOB_RELOAD] = "reload",
939         [JOB_RELOAD_OR_START] = "reload-or-start",
940         [JOB_RESTART] = "restart",
941         [JOB_TRY_RESTART] = "try-restart",
942         [JOB_NOP] = "nop",
943 };
944
945 DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
946
947 static const char* const job_mode_table[_JOB_MODE_MAX] = {
948         [JOB_FAIL] = "fail",
949         [JOB_REPLACE] = "replace",
950         [JOB_ISOLATE] = "isolate",
951         [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
952         [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements"
953 };
954
955 DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
956
957 static const char* const job_result_table[_JOB_RESULT_MAX] = {
958         [JOB_DONE] = "done",
959         [JOB_CANCELED] = "canceled",
960         [JOB_TIMEOUT] = "timeout",
961         [JOB_FAILED] = "failed",
962         [JOB_DEPENDENCY] = "dependency",
963         [JOB_SKIPPED] = "skipped"
964 };
965
966 DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);