chiark / gitweb /
8d51aa3fdd7036be8286f3acb2cd3b45663bf84a
[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 || t == JOB_RESTART) {
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         } else if (t == JOB_VERIFY_ACTIVE) {
612
613                 /* When verify-active detects the unit is inactive, report it.
614                  * Most likely a DEPEND warning from a requisiting unit will
615                  * occur next and it's nice to see what was requisited. */
616                 if (result == JOB_SKIPPED)
617                         unit_status_printf(u, ANSI_HIGHLIGHT_ON " INFO " ANSI_HIGHLIGHT_OFF, "%s is not active.", unit_description(u));
618         }
619 }
620
621 int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
622         Unit *u;
623         Unit *other;
624         JobType t;
625         Iterator i;
626
627         assert(j);
628         assert(j->installed);
629         assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
630
631         u = j->unit;
632         t = j->type;
633
634         j->result = result;
635
636         log_debug("Job %s/%s finished, result=%s", u->id, job_type_to_string(t), job_result_to_string(result));
637
638         job_print_status_message(u, t, result);
639
640         job_add_to_dbus_queue(j);
641
642         /* Patch restart jobs so that they become normal start jobs */
643         if (result == JOB_DONE && t == JOB_RESTART) {
644
645                 job_change_type(j, JOB_START);
646                 j->state = JOB_WAITING;
647
648                 job_add_to_run_queue(j);
649
650                 goto finish;
651         }
652
653         if (result == JOB_FAILED)
654                 j->manager->n_failed_jobs ++;
655
656         job_uninstall(j);
657         job_free(j);
658
659         /* Fail depending jobs on failure */
660         if (result != JOB_DONE && recursive) {
661
662                 if (t == JOB_START ||
663                     t == JOB_VERIFY_ACTIVE) {
664
665                         SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
666                                 if (other->job &&
667                                     (other->job->type == JOB_START ||
668                                      other->job->type == JOB_VERIFY_ACTIVE))
669                                         job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
670
671                         SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
672                                 if (other->job &&
673                                     (other->job->type == JOB_START ||
674                                      other->job->type == JOB_VERIFY_ACTIVE))
675                                         job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
676
677                         SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
678                                 if (other->job &&
679                                     !other->job->override &&
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                 } else if (t == JOB_STOP) {
685
686                         SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
687                                 if (other->job &&
688                                     (other->job->type == JOB_START ||
689                                      other->job->type == JOB_VERIFY_ACTIVE))
690                                         job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
691                 }
692         }
693
694         /* Trigger OnFailure dependencies that are not generated by
695          * the unit itself. We don't tread JOB_CANCELED as failure in
696          * this context. And JOB_FAILURE is already handled by the
697          * unit itself. */
698         if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) {
699                 log_notice("Job %s/%s failed with result '%s'.",
700                            u->id,
701                            job_type_to_string(t),
702                            job_result_to_string(result));
703
704                 unit_trigger_on_failure(u);
705         }
706
707 finish:
708         /* Try to start the next jobs that can be started */
709         SET_FOREACH(other, u->dependencies[UNIT_AFTER], i)
710                 if (other->job)
711                         job_add_to_run_queue(other->job);
712         SET_FOREACH(other, u->dependencies[UNIT_BEFORE], i)
713                 if (other->job)
714                         job_add_to_run_queue(other->job);
715
716         manager_check_finished(u->manager);
717
718         return 0;
719 }
720
721 int job_start_timer(Job *j) {
722         struct itimerspec its;
723         struct epoll_event ev;
724         int fd, r;
725         assert(j);
726
727         if (j->unit->job_timeout <= 0 ||
728             j->timer_watch.type == WATCH_JOB_TIMER)
729                 return 0;
730
731         assert(j->timer_watch.type == WATCH_INVALID);
732
733         if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) {
734                 r = -errno;
735                 goto fail;
736         }
737
738         zero(its);
739         timespec_store(&its.it_value, j->unit->job_timeout);
740
741         if (timerfd_settime(fd, 0, &its, NULL) < 0) {
742                 r = -errno;
743                 goto fail;
744         }
745
746         zero(ev);
747         ev.data.ptr = &j->timer_watch;
748         ev.events = EPOLLIN;
749
750         if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
751                 r = -errno;
752                 goto fail;
753         }
754
755         j->timer_watch.type = WATCH_JOB_TIMER;
756         j->timer_watch.fd = fd;
757         j->timer_watch.data.job = j;
758
759         return 0;
760
761 fail:
762         if (fd >= 0)
763                 close_nointr_nofail(fd);
764
765         return r;
766 }
767
768 void job_add_to_run_queue(Job *j) {
769         assert(j);
770         assert(j->installed);
771
772         if (j->in_run_queue)
773                 return;
774
775         LIST_PREPEND(Job, run_queue, j->manager->run_queue, j);
776         j->in_run_queue = true;
777 }
778
779 void job_add_to_dbus_queue(Job *j) {
780         assert(j);
781         assert(j->installed);
782
783         if (j->in_dbus_queue)
784                 return;
785
786         /* We don't check if anybody is subscribed here, since this
787          * job might just have been created and not yet assigned to a
788          * connection/client. */
789
790         LIST_PREPEND(Job, dbus_queue, j->manager->dbus_job_queue, j);
791         j->in_dbus_queue = true;
792 }
793
794 char *job_dbus_path(Job *j) {
795         char *p;
796
797         assert(j);
798
799         if (asprintf(&p, "/org/freedesktop/systemd1/job/%lu", (unsigned long) j->id) < 0)
800                 return NULL;
801
802         return p;
803 }
804
805 void job_timer_event(Job *j, uint64_t n_elapsed, Watch *w) {
806         assert(j);
807         assert(w == &j->timer_watch);
808
809         log_warning("Job %s/%s timed out.", j->unit->id, job_type_to_string(j->type));
810         job_finish_and_invalidate(j, JOB_TIMEOUT, true);
811 }
812
813 int job_serialize(Job *j, FILE *f, FDSet *fds) {
814         fprintf(f, "job-id=%u\n", j->id);
815         fprintf(f, "job-type=%s\n", job_type_to_string(j->type));
816         fprintf(f, "job-state=%s\n", job_state_to_string(j->state));
817         fprintf(f, "job-override=%s\n", yes_no(j->override));
818         fprintf(f, "job-sent-dbus-new-signal=%s\n", yes_no(j->sent_dbus_new_signal));
819         fprintf(f, "job-ignore-order=%s\n", yes_no(j->ignore_order));
820         /* Cannot save bus clients. Just note the fact that we're losing
821          * them. job_send_message() will fallback to broadcasting. */
822         fprintf(f, "job-forgot-bus-clients=%s\n",
823                 yes_no(j->forgot_bus_clients || j->bus_client_list));
824         if (j->timer_watch.type == WATCH_JOB_TIMER) {
825                 int copy = fdset_put_dup(fds, j->timer_watch.fd);
826                 if (copy < 0)
827                         return copy;
828                 fprintf(f, "job-timer-watch-fd=%d\n", copy);
829         }
830
831         /* End marker */
832         fputc('\n', f);
833         return 0;
834 }
835
836 int job_deserialize(Job *j, FILE *f, FDSet *fds) {
837         for (;;) {
838                 char line[LINE_MAX], *l, *v;
839                 size_t k;
840
841                 if (!fgets(line, sizeof(line), f)) {
842                         if (feof(f))
843                                 return 0;
844                         return -errno;
845                 }
846
847                 char_array_0(line);
848                 l = strstrip(line);
849
850                 /* End marker */
851                 if (l[0] == 0)
852                         return 0;
853
854                 k = strcspn(l, "=");
855
856                 if (l[k] == '=') {
857                         l[k] = 0;
858                         v = l+k+1;
859                 } else
860                         v = l+k;
861
862                 if (streq(l, "job-id")) {
863                         if (safe_atou32(v, &j->id) < 0)
864                                 log_debug("Failed to parse job id value %s", v);
865                 } else if (streq(l, "job-type")) {
866                         JobType t = job_type_from_string(v);
867                         if (t < 0)
868                                 log_debug("Failed to parse job type %s", v);
869                         else if (t >= _JOB_TYPE_MAX_IN_TRANSACTION)
870                                 log_debug("Cannot deserialize job of type %s", v);
871                         else
872                                 j->type = t;
873                 } else if (streq(l, "job-state")) {
874                         JobState s = job_state_from_string(v);
875                         if (s < 0)
876                                 log_debug("Failed to parse job state %s", v);
877                         else
878                                 j->state = s;
879                 } else if (streq(l, "job-override")) {
880                         int b = parse_boolean(v);
881                         if (b < 0)
882                                 log_debug("Failed to parse job override flag %s", v);
883                         else
884                                 j->override = j->override || b;
885                 } else if (streq(l, "job-sent-dbus-new-signal")) {
886                         int b = parse_boolean(v);
887                         if (b < 0)
888                                 log_debug("Failed to parse job sent_dbus_new_signal flag %s", v);
889                         else
890                                 j->sent_dbus_new_signal = j->sent_dbus_new_signal || b;
891                 } else if (streq(l, "job-ignore-order")) {
892                         int b = parse_boolean(v);
893                         if (b < 0)
894                                 log_debug("Failed to parse job ignore_order flag %s", v);
895                         else
896                                 j->ignore_order = j->ignore_order || b;
897                 } else if (streq(l, "job-forgot-bus-clients")) {
898                         int b = parse_boolean(v);
899                         if (b < 0)
900                                 log_debug("Failed to parse job forgot_bus_clients flag %s", v);
901                         else
902                                 j->forgot_bus_clients = j->forgot_bus_clients || b;
903                 } else if (streq(l, "job-timer-watch-fd")) {
904                         int fd;
905                         if (safe_atoi(v, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
906                                 log_debug("Failed to parse job-timer-watch-fd value %s", v);
907                         else {
908                                 if (j->timer_watch.type == WATCH_JOB_TIMER)
909                                         close_nointr_nofail(j->timer_watch.fd);
910
911                                 j->timer_watch.type = WATCH_JOB_TIMER;
912                                 j->timer_watch.fd = fdset_remove(fds, fd);
913                                 j->timer_watch.data.job = j;
914                         }
915                 }
916         }
917 }
918
919 int job_coldplug(Job *j) {
920         struct epoll_event ev;
921
922         if (j->timer_watch.type != WATCH_JOB_TIMER)
923                 return 0;
924
925         zero(ev);
926         ev.data.ptr = &j->timer_watch;
927         ev.events = EPOLLIN;
928
929         if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, j->timer_watch.fd, &ev) < 0)
930                 return -errno;
931
932         return 0;
933 }
934
935 static const char* const job_state_table[_JOB_STATE_MAX] = {
936         [JOB_WAITING] = "waiting",
937         [JOB_RUNNING] = "running"
938 };
939
940 DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
941
942 static const char* const job_type_table[_JOB_TYPE_MAX] = {
943         [JOB_START] = "start",
944         [JOB_VERIFY_ACTIVE] = "verify-active",
945         [JOB_STOP] = "stop",
946         [JOB_RELOAD] = "reload",
947         [JOB_RELOAD_OR_START] = "reload-or-start",
948         [JOB_RESTART] = "restart",
949         [JOB_TRY_RESTART] = "try-restart",
950         [JOB_NOP] = "nop",
951 };
952
953 DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
954
955 static const char* const job_mode_table[_JOB_MODE_MAX] = {
956         [JOB_FAIL] = "fail",
957         [JOB_REPLACE] = "replace",
958         [JOB_ISOLATE] = "isolate",
959         [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
960         [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements"
961 };
962
963 DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
964
965 static const char* const job_result_table[_JOB_RESULT_MAX] = {
966         [JOB_DONE] = "done",
967         [JOB_CANCELED] = "canceled",
968         [JOB_TIMEOUT] = "timeout",
969         [JOB_FAILED] = "failed",
970         [JOB_DEPENDENCY] = "dependency",
971         [JOB_SKIPPED] = "skipped"
972 };
973
974 DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);