chiark / gitweb /
execute: optionally ignore return status of invoked commands
[elogind.git] / src / load-fragment.c
1 /*-*- Mode: C; c-basic-offset: 8 -*-*/
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 General Public License as published by
10   the Free Software Foundation; either version 2 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   General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <linux/oom.h>
23 #include <assert.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <sched.h>
29 #include <sys/prctl.h>
30 #include <sys/mount.h>
31 #include <linux/fs.h>
32
33 #include "unit.h"
34 #include "strv.h"
35 #include "conf-parser.h"
36 #include "load-fragment.h"
37 #include "log.h"
38 #include "ioprio.h"
39 #include "securebits.h"
40 #include "missing.h"
41 #include "unit-name.h"
42 #include "bus-errors.h"
43
44 #define COMMENTS "#;\n"
45
46 static int config_parse_deps(
47                 const char *filename,
48                 unsigned line,
49                 const char *section,
50                 const char *lvalue,
51                 const char *rvalue,
52                 void *data,
53                 void *userdata) {
54
55         UnitDependency d = PTR_TO_UINT(data);
56         Unit *u = userdata;
57         char *w;
58         size_t l;
59         char *state;
60
61         assert(filename);
62         assert(lvalue);
63         assert(rvalue);
64
65         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
66                 char *t, *k;
67                 int r;
68
69                 if (!(t = strndup(w, l)))
70                         return -ENOMEM;
71
72                 k = unit_name_printf(u, t);
73                 free(t);
74
75                 if (!k)
76                         return -ENOMEM;
77
78                 r = unit_add_dependency_by_name(u, d, k, NULL, true);
79                 free(k);
80
81                 if (r < 0)
82                         return r;
83         }
84
85         return 0;
86 }
87
88 static int config_parse_names(
89                 const char *filename,
90                 unsigned line,
91                 const char *section,
92                 const char *lvalue,
93                 const char *rvalue,
94                 void *data,
95                 void *userdata) {
96
97         Unit *u = userdata;
98         char *w;
99         size_t l;
100         char *state;
101
102         assert(filename);
103         assert(lvalue);
104         assert(rvalue);
105         assert(data);
106
107         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
108                 char *t, *k;
109                 int r;
110
111                 if (!(t = strndup(w, l)))
112                         return -ENOMEM;
113
114                 k = unit_name_printf(u, t);
115                 free(t);
116
117                 if (!k)
118                         return -ENOMEM;
119
120                 r = unit_merge_by_name(u, k);
121                 free(k);
122
123                 if (r < 0)
124                         return r;
125         }
126
127         return 0;
128 }
129
130 static int config_parse_string_printf(
131                 const char *filename,
132                 unsigned line,
133                 const char *section,
134                 const char *lvalue,
135                 const char *rvalue,
136                 void *data,
137                 void *userdata) {
138
139         Unit *u = userdata;
140         char **s = data;
141         char *k;
142
143         assert(filename);
144         assert(lvalue);
145         assert(rvalue);
146         assert(s);
147         assert(u);
148
149         if (!(k = unit_full_printf(u, rvalue)))
150                 return -ENOMEM;
151
152         free(*s);
153         if (*k)
154                 *s = k;
155         else {
156                 free(k);
157                 *s = NULL;
158         }
159
160         return 0;
161 }
162
163 static int config_parse_listen(
164                 const char *filename,
165                 unsigned line,
166                 const char *section,
167                 const char *lvalue,
168                 const char *rvalue,
169                 void *data,
170                 void *userdata) {
171
172         int r;
173         SocketPort *p;
174         Socket *s;
175
176         assert(filename);
177         assert(lvalue);
178         assert(rvalue);
179         assert(data);
180
181         s = (Socket*) data;
182
183         if (!(p = new0(SocketPort, 1)))
184                 return -ENOMEM;
185
186         if (streq(lvalue, "ListenFIFO")) {
187                 p->type = SOCKET_FIFO;
188
189                 if (!(p->path = strdup(rvalue))) {
190                         free(p);
191                         return -ENOMEM;
192                 }
193
194                 path_kill_slashes(p->path);
195         } else {
196                 p->type = SOCKET_SOCKET;
197
198                 if ((r = socket_address_parse(&p->address, rvalue)) < 0) {
199                         log_error("[%s:%u] Failed to parse address value: %s", filename, line, rvalue);
200                         free(p);
201                         return r;
202                 }
203
204                 if (streq(lvalue, "ListenStream"))
205                         p->address.type = SOCK_STREAM;
206                 else if (streq(lvalue, "ListenDatagram"))
207                         p->address.type = SOCK_DGRAM;
208                 else {
209                         assert(streq(lvalue, "ListenSequentialPacket"));
210                         p->address.type = SOCK_SEQPACKET;
211                 }
212
213                 if (socket_address_family(&p->address) != AF_LOCAL && p->address.type == SOCK_SEQPACKET) {
214                         free(p);
215                         return -EPROTONOSUPPORT;
216                 }
217         }
218
219         p->fd = -1;
220         LIST_PREPEND(SocketPort, port, s->ports, p);
221
222         return 0;
223 }
224
225 static int config_parse_socket_bind(
226                 const char *filename,
227                 unsigned line,
228                 const char *section,
229                 const char *lvalue,
230                 const char *rvalue,
231                 void *data,
232                 void *userdata) {
233
234         Socket *s;
235         SocketAddressBindIPv6Only b;
236
237         assert(filename);
238         assert(lvalue);
239         assert(rvalue);
240         assert(data);
241
242         s = (Socket*) data;
243
244         if ((b = socket_address_bind_ipv6_only_from_string(rvalue)) < 0) {
245                 int r;
246
247                 if ((r = parse_boolean(rvalue)) < 0) {
248                         log_error("[%s:%u] Failed to parse bind IPv6 only value: %s", filename, line, rvalue);
249                         return -EBADMSG;
250                 }
251
252                 s->bind_ipv6_only = r ? SOCKET_ADDRESS_IPV6_ONLY : SOCKET_ADDRESS_BOTH;
253         } else
254                 s->bind_ipv6_only = b;
255
256         return 0;
257 }
258
259 static int config_parse_nice(
260                 const char *filename,
261                 unsigned line,
262                 const char *section,
263                 const char *lvalue,
264                 const char *rvalue,
265                 void *data,
266                 void *userdata) {
267
268         ExecContext *c = data;
269         int priority, r;
270
271         assert(filename);
272         assert(lvalue);
273         assert(rvalue);
274         assert(data);
275
276         if ((r = safe_atoi(rvalue, &priority)) < 0) {
277                 log_error("[%s:%u] Failed to parse nice priority: %s", filename, line, rvalue);
278                 return r;
279         }
280
281         if (priority < PRIO_MIN || priority >= PRIO_MAX) {
282                 log_error("[%s:%u] Nice priority out of range: %s", filename, line, rvalue);
283                 return -ERANGE;
284         }
285
286         c->nice = priority;
287         c->nice_set = false;
288
289         return 0;
290 }
291
292 static int config_parse_oom_adjust(
293                 const char *filename,
294                 unsigned line,
295                 const char *section,
296                 const char *lvalue,
297                 const char *rvalue,
298                 void *data,
299                 void *userdata) {
300
301         ExecContext *c = data;
302         int oa, r;
303
304         assert(filename);
305         assert(lvalue);
306         assert(rvalue);
307         assert(data);
308
309         if ((r = safe_atoi(rvalue, &oa)) < 0) {
310                 log_error("[%s:%u] Failed to parse OOM adjust value: %s", filename, line, rvalue);
311                 return r;
312         }
313
314         if (oa < OOM_DISABLE || oa > OOM_ADJUST_MAX) {
315                 log_error("[%s:%u] OOM adjust value out of range: %s", filename, line, rvalue);
316                 return -ERANGE;
317         }
318
319         c->oom_adjust = oa;
320         c->oom_adjust_set = true;
321
322         return 0;
323 }
324
325 static int config_parse_mode(
326                 const char *filename,
327                 unsigned line,
328                 const char *section,
329                 const char *lvalue,
330                 const char *rvalue,
331                 void *data,
332                 void *userdata) {
333
334         mode_t *m = data;
335         long l;
336         char *x = NULL;
337
338         assert(filename);
339         assert(lvalue);
340         assert(rvalue);
341         assert(data);
342
343         errno = 0;
344         l = strtol(rvalue, &x, 8);
345         if (!x || *x || errno) {
346                 log_error("[%s:%u] Failed to parse mode value: %s", filename, line, rvalue);
347                 return errno ? -errno : -EINVAL;
348         }
349
350         if (l < 0000 || l > 07777) {
351                 log_error("[%s:%u] mode value out of range: %s", filename, line, rvalue);
352                 return -ERANGE;
353         }
354
355         *m = (mode_t) l;
356         return 0;
357 }
358
359 static int config_parse_exec(
360                 const char *filename,
361                 unsigned line,
362                 const char *section,
363                 const char *lvalue,
364                 const char *rvalue,
365                 void *data,
366                 void *userdata) {
367
368         ExecCommand **e = data, *nce;
369         char *path, **n;
370         unsigned k;
371
372         assert(filename);
373         assert(lvalue);
374         assert(rvalue);
375         assert(e);
376
377         /* We accept an absolute path as first argument, or
378          * alternatively an absolute prefixed with @ to allow
379          * overriding of argv[0]. */
380
381         for (;;) {
382                 char *w;
383                 size_t l;
384                 char *state;
385                 bool honour_argv0 = false, ignore = false;
386
387                 path = NULL;
388                 nce = NULL;
389                 n = NULL;
390
391                 rvalue += strspn(rvalue, WHITESPACE);
392
393                 if (rvalue[0] == 0)
394                         break;
395
396                 if (rvalue[0] == '-') {
397                         ignore = true;
398                         rvalue ++;
399                 }
400
401                 if (rvalue[0] == '@') {
402                         honour_argv0 = true;
403                         rvalue ++;
404                 }
405
406                 if (*rvalue != '/') {
407                         log_error("[%s:%u] Invalid executable path in command line: %s", filename, line, rvalue);
408                         return -EINVAL;
409                 }
410
411                 k = 0;
412                 FOREACH_WORD_QUOTED(w, l, rvalue, state) {
413                         if (strncmp(w, ";", l) == 0)
414                                 break;
415
416                         k++;
417                 }
418
419                 if (!(n = new(char*, k + !honour_argv0)))
420                         return -ENOMEM;
421
422                 k = 0;
423                 FOREACH_WORD_QUOTED(w, l, rvalue, state) {
424                         if (strncmp(w, ";", l) == 0)
425                                 break;
426
427                         if (honour_argv0 && w == rvalue) {
428                                 assert(!path);
429                                 if (!(path = cunescape_length(w, l)))
430                                         goto fail;
431                         } else {
432                                 if (!(n[k++] = cunescape_length(w, l)))
433                                         goto fail;
434                         }
435                 }
436
437                 n[k] = NULL;
438
439                 if (!n[0]) {
440                         log_error("[%s:%u] Invalid command line: %s", filename, line, rvalue);
441                         strv_free(n);
442                         return -EINVAL;
443                 }
444
445                 if (!path)
446                         if (!(path = strdup(n[0])))
447                                 goto fail;
448
449                 assert(path_is_absolute(path));
450
451                 if (!(nce = new0(ExecCommand, 1)))
452                         goto fail;
453
454                 nce->argv = n;
455                 nce->path = path;
456                 nce->ignore = ignore;
457
458                 path_kill_slashes(nce->path);
459
460                 exec_command_append_list(e, nce);
461
462                 rvalue = state;
463         }
464
465         return 0;
466
467 fail:
468         n[k] = NULL;
469         strv_free(n);
470         free(path);
471         free(nce);
472
473         return -ENOMEM;
474 }
475
476 static int config_parse_usec(
477                 const char *filename,
478                 unsigned line,
479                 const char *section,
480                 const char *lvalue,
481                 const char *rvalue,
482                 void *data,
483                 void *userdata) {
484
485         usec_t *usec = data;
486         int r;
487
488         assert(filename);
489         assert(lvalue);
490         assert(rvalue);
491         assert(data);
492
493         if ((r = parse_usec(rvalue, usec)) < 0) {
494                 log_error("[%s:%u] Failed to parse time value: %s", filename, line, rvalue);
495                 return r;
496         }
497
498         return 0;
499 }
500
501 static DEFINE_CONFIG_PARSE_ENUM(config_parse_service_type, service_type, ServiceType, "Failed to parse service type");
502 static DEFINE_CONFIG_PARSE_ENUM(config_parse_service_restart, service_restart, ServiceRestart, "Failed to parse service restart specifier");
503
504 static int config_parse_bindtodevice(
505                 const char *filename,
506                 unsigned line,
507                 const char *section,
508                 const char *lvalue,
509                 const char *rvalue,
510                 void *data,
511                 void *userdata) {
512
513         Socket *s = data;
514         char *n;
515
516         assert(filename);
517         assert(lvalue);
518         assert(rvalue);
519         assert(data);
520
521         if (rvalue[0] && !streq(rvalue, "*")) {
522                 if (!(n = strdup(rvalue)))
523                         return -ENOMEM;
524         } else
525                 n = NULL;
526
527         free(s->bind_to_device);
528         s->bind_to_device = n;
529
530         return 0;
531 }
532
533 static DEFINE_CONFIG_PARSE_ENUM(config_parse_output, exec_output, ExecOutput, "Failed to parse output specifier");
534 static DEFINE_CONFIG_PARSE_ENUM(config_parse_input, exec_input, ExecInput, "Failed to parse input specifier");
535
536 static int config_parse_facility(
537                 const char *filename,
538                 unsigned line,
539                 const char *section,
540                 const char *lvalue,
541                 const char *rvalue,
542                 void *data,
543                 void *userdata) {
544
545
546         int *o = data, x;
547
548         assert(filename);
549         assert(lvalue);
550         assert(rvalue);
551         assert(data);
552
553         if ((x = log_facility_from_string(rvalue)) < 0) {
554                 log_error("[%s:%u] Failed to parse log facility: %s", filename, line, rvalue);
555                 return -EBADMSG;
556         }
557
558         *o = LOG_MAKEPRI(x, LOG_PRI(*o));
559
560         return 0;
561 }
562
563 static int config_parse_level(
564                 const char *filename,
565                 unsigned line,
566                 const char *section,
567                 const char *lvalue,
568                 const char *rvalue,
569                 void *data,
570                 void *userdata) {
571
572
573         int *o = data, x;
574
575         assert(filename);
576         assert(lvalue);
577         assert(rvalue);
578         assert(data);
579
580         if ((x = log_level_from_string(rvalue)) < 0) {
581                 log_error("[%s:%u] Failed to parse log level: %s", filename, line, rvalue);
582                 return -EBADMSG;
583         }
584
585         *o = LOG_MAKEPRI(LOG_FAC(*o), x);
586         return 0;
587 }
588
589 static int config_parse_io_class(
590                 const char *filename,
591                 unsigned line,
592                 const char *section,
593                 const char *lvalue,
594                 const char *rvalue,
595                 void *data,
596                 void *userdata) {
597
598         ExecContext *c = data;
599         int x;
600
601         assert(filename);
602         assert(lvalue);
603         assert(rvalue);
604         assert(data);
605
606         if ((x = ioprio_class_from_string(rvalue)) < 0) {
607                 log_error("[%s:%u] Failed to parse IO scheduling class: %s", filename, line, rvalue);
608                 return -EBADMSG;
609         }
610
611         c->ioprio = IOPRIO_PRIO_VALUE(x, IOPRIO_PRIO_DATA(c->ioprio));
612         c->ioprio_set = true;
613
614         return 0;
615 }
616
617 static int config_parse_io_priority(
618                 const char *filename,
619                 unsigned line,
620                 const char *section,
621                 const char *lvalue,
622                 const char *rvalue,
623                 void *data,
624                 void *userdata) {
625
626         ExecContext *c = data;
627         int i;
628
629         assert(filename);
630         assert(lvalue);
631         assert(rvalue);
632         assert(data);
633
634         if (safe_atoi(rvalue, &i) < 0 || i < 0 || i >= IOPRIO_BE_NR) {
635                 log_error("[%s:%u] Failed to parse io priority: %s", filename, line, rvalue);
636                 return -EBADMSG;
637         }
638
639         c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), i);
640         c->ioprio_set = true;
641
642         return 0;
643 }
644
645 static int config_parse_cpu_sched_policy(
646                 const char *filename,
647                 unsigned line,
648                 const char *section,
649                 const char *lvalue,
650                 const char *rvalue,
651                 void *data,
652                 void *userdata) {
653
654
655         ExecContext *c = data;
656         int x;
657
658         assert(filename);
659         assert(lvalue);
660         assert(rvalue);
661         assert(data);
662
663         if ((x = sched_policy_from_string(rvalue)) < 0) {
664                 log_error("[%s:%u] Failed to parse CPU scheduling policy: %s", filename, line, rvalue);
665                 return -EBADMSG;
666         }
667
668         c->cpu_sched_policy = x;
669         c->cpu_sched_set = true;
670
671         return 0;
672 }
673
674 static int config_parse_cpu_sched_prio(
675                 const char *filename,
676                 unsigned line,
677                 const char *section,
678                 const char *lvalue,
679                 const char *rvalue,
680                 void *data,
681                 void *userdata) {
682
683         ExecContext *c = data;
684         int i;
685
686         assert(filename);
687         assert(lvalue);
688         assert(rvalue);
689         assert(data);
690
691         /* On Linux RR/FIFO have the same range */
692         if (safe_atoi(rvalue, &i) < 0 || i < sched_get_priority_min(SCHED_RR) || i > sched_get_priority_max(SCHED_RR)) {
693                 log_error("[%s:%u] Failed to parse CPU scheduling priority: %s", filename, line, rvalue);
694                 return -EBADMSG;
695         }
696
697         c->cpu_sched_priority = i;
698         c->cpu_sched_set = true;
699
700         return 0;
701 }
702
703 static int config_parse_cpu_affinity(
704                 const char *filename,
705                 unsigned line,
706                 const char *section,
707                 const char *lvalue,
708                 const char *rvalue,
709                 void *data,
710                 void *userdata) {
711
712         ExecContext *c = data;
713         char *w;
714         size_t l;
715         char *state;
716
717         assert(filename);
718         assert(lvalue);
719         assert(rvalue);
720         assert(data);
721
722         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
723                 char *t;
724                 int r;
725                 unsigned cpu;
726
727                 if (!(t = strndup(w, l)))
728                         return -ENOMEM;
729
730                 r = safe_atou(t, &cpu);
731                 free(t);
732
733                 if (!(c->cpuset))
734                         if (!(c->cpuset = cpu_set_malloc(&c->cpuset_ncpus)))
735                                 return -ENOMEM;
736
737                 if (r < 0 || cpu >= c->cpuset_ncpus) {
738                         log_error("[%s:%u] Failed to parse CPU affinity: %s", filename, line, rvalue);
739                         return -EBADMSG;
740                 }
741
742                 CPU_SET_S(cpu, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset);
743         }
744
745         return 0;
746 }
747
748 static int config_parse_capabilities(
749                 const char *filename,
750                 unsigned line,
751                 const char *section,
752                 const char *lvalue,
753                 const char *rvalue,
754                 void *data,
755                 void *userdata) {
756
757         ExecContext *c = data;
758         cap_t cap;
759
760         assert(filename);
761         assert(lvalue);
762         assert(rvalue);
763         assert(data);
764
765         if (!(cap = cap_from_text(rvalue))) {
766                 if (errno == ENOMEM)
767                         return -ENOMEM;
768
769                 log_error("[%s:%u] Failed to parse capabilities: %s", filename, line, rvalue);
770                 return -EBADMSG;
771         }
772
773         if (c->capabilities)
774                 cap_free(c->capabilities);
775         c->capabilities = cap;
776
777         return 0;
778 }
779
780 static int config_parse_secure_bits(
781                 const char *filename,
782                 unsigned line,
783                 const char *section,
784                 const char *lvalue,
785                 const char *rvalue,
786                 void *data,
787                 void *userdata) {
788
789         ExecContext *c = data;
790         char *w;
791         size_t l;
792         char *state;
793
794         assert(filename);
795         assert(lvalue);
796         assert(rvalue);
797         assert(data);
798
799         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
800                 if (first_word(w, "keep-caps"))
801                         c->secure_bits |= SECURE_KEEP_CAPS;
802                 else if (first_word(w, "keep-caps-locked"))
803                         c->secure_bits |= SECURE_KEEP_CAPS_LOCKED;
804                 else if (first_word(w, "no-setuid-fixup"))
805                         c->secure_bits |= SECURE_NO_SETUID_FIXUP;
806                 else if (first_word(w, "no-setuid-fixup-locked"))
807                         c->secure_bits |= SECURE_NO_SETUID_FIXUP_LOCKED;
808                 else if (first_word(w, "noroot"))
809                         c->secure_bits |= SECURE_NOROOT;
810                 else if (first_word(w, "noroot-locked"))
811                         c->secure_bits |= SECURE_NOROOT_LOCKED;
812                 else {
813                         log_error("[%s:%u] Failed to parse secure bits: %s", filename, line, rvalue);
814                         return -EBADMSG;
815                 }
816         }
817
818         return 0;
819 }
820
821 static int config_parse_bounding_set(
822                 const char *filename,
823                 unsigned line,
824                 const char *section,
825                 const char *lvalue,
826                 const char *rvalue,
827                 void *data,
828                 void *userdata) {
829
830         ExecContext *c = data;
831         char *w;
832         size_t l;
833         char *state;
834
835         assert(filename);
836         assert(lvalue);
837         assert(rvalue);
838         assert(data);
839
840         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
841                 char *t;
842                 int r;
843                 cap_value_t cap;
844
845                 if (!(t = strndup(w, l)))
846                         return -ENOMEM;
847
848                 r = cap_from_name(t, &cap);
849                 free(t);
850
851                 if (r < 0) {
852                         log_error("[%s:%u] Failed to parse capability bounding set: %s", filename, line, rvalue);
853                         return -EBADMSG;
854                 }
855
856                 c->capability_bounding_set_drop |= 1 << cap;
857         }
858
859         return 0;
860 }
861
862 static int config_parse_timer_slack_nsec(
863                 const char *filename,
864                 unsigned line,
865                 const char *section,
866                 const char *lvalue,
867                 const char *rvalue,
868                 void *data,
869                 void *userdata) {
870
871         ExecContext *c = data;
872         unsigned long u;
873         int r;
874
875         assert(filename);
876         assert(lvalue);
877         assert(rvalue);
878         assert(data);
879
880         if ((r = safe_atolu(rvalue, &u)) < 0) {
881                 log_error("[%s:%u] Failed to parse time slack value: %s", filename, line, rvalue);
882                 return r;
883         }
884
885         c->timer_slack_nsec = u;
886
887         return 0;
888 }
889
890 static int config_parse_limit(
891                 const char *filename,
892                 unsigned line,
893                 const char *section,
894                 const char *lvalue,
895                 const char *rvalue,
896                 void *data,
897                 void *userdata) {
898
899         struct rlimit **rl = data;
900         unsigned long long u;
901         int r;
902
903         assert(filename);
904         assert(lvalue);
905         assert(rvalue);
906         assert(data);
907
908         if ((r = safe_atollu(rvalue, &u)) < 0) {
909                 log_error("[%s:%u] Failed to parse resource value: %s", filename, line, rvalue);
910                 return r;
911         }
912
913         if (!*rl)
914                 if (!(*rl = new(struct rlimit, 1)))
915                         return -ENOMEM;
916
917         (*rl)->rlim_cur = (*rl)->rlim_max = (rlim_t) u;
918         return 0;
919 }
920
921 static int config_parse_cgroup(
922                 const char *filename,
923                 unsigned line,
924                 const char *section,
925                 const char *lvalue,
926                 const char *rvalue,
927                 void *data,
928                 void *userdata) {
929
930         Unit *u = userdata;
931         char *w;
932         size_t l;
933         char *state;
934
935         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
936                 char *t;
937                 int r;
938
939                 if (!(t = cunescape_length(w, l)))
940                         return -ENOMEM;
941
942                 r = unit_add_cgroup_from_text(u, t);
943                 free(t);
944
945                 if (r < 0)
946                         return r;
947         }
948
949         return 0;
950 }
951
952 static int config_parse_sysv_priority(
953                 const char *filename,
954                 unsigned line,
955                 const char *section,
956                 const char *lvalue,
957                 const char *rvalue,
958                 void *data,
959                 void *userdata) {
960
961         int *priority = data;
962         int r, i;
963
964         assert(filename);
965         assert(lvalue);
966         assert(rvalue);
967         assert(data);
968
969         if ((r = safe_atoi(rvalue, &i)) < 0 || i < 0) {
970                 log_error("[%s:%u] Failed to parse SysV start priority: %s", filename, line, rvalue);
971                 return r;
972         }
973
974         *priority = (int) i;
975         return 0;
976 }
977
978 static DEFINE_CONFIG_PARSE_ENUM(config_parse_kill_mode, kill_mode, KillMode, "Failed to parse kill mode");
979
980 static int config_parse_kill_signal(
981                 const char *filename,
982                 unsigned line,
983                 const char *section,
984                 const char *lvalue,
985                 const char *rvalue,
986                 void *data,
987                 void *userdata) {
988
989         int *sig = data;
990         int r;
991
992         assert(filename);
993         assert(lvalue);
994         assert(rvalue);
995         assert(sig);
996
997         if ((r = signal_from_string(rvalue)) <= 0)
998                 if (startswith(rvalue, "SIG"))
999                         r = signal_from_string(rvalue+3);
1000
1001         if (r <= 0) {
1002                 log_error("[%s:%u] Failed to parse kill signal: %s", filename, line, rvalue);
1003                 return -EINVAL;
1004         }
1005
1006         *sig = r;
1007         return 0;
1008 }
1009
1010 static int config_parse_mount_flags(
1011                 const char *filename,
1012                 unsigned line,
1013                 const char *section,
1014                 const char *lvalue,
1015                 const char *rvalue,
1016                 void *data,
1017                 void *userdata) {
1018
1019         ExecContext *c = data;
1020         char *w;
1021         size_t l;
1022         char *state;
1023         unsigned long flags = 0;
1024
1025         assert(filename);
1026         assert(lvalue);
1027         assert(rvalue);
1028         assert(data);
1029
1030         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
1031                 if (strncmp(w, "shared", l) == 0)
1032                         flags |= MS_SHARED;
1033                 else if (strncmp(w, "slave", l) == 0)
1034                         flags |= MS_SLAVE;
1035                 else if (strncmp(w, "private", l) == 0)
1036                         flags |= MS_PRIVATE;
1037                 else {
1038                         log_error("[%s:%u] Failed to parse mount flags: %s", filename, line, rvalue);
1039                         return -EINVAL;
1040                 }
1041         }
1042
1043         c->mount_flags = flags;
1044         return 0;
1045 }
1046
1047 static int config_parse_timer(
1048                 const char *filename,
1049                 unsigned line,
1050                 const char *section,
1051                 const char *lvalue,
1052                 const char *rvalue,
1053                 void *data,
1054                 void *userdata) {
1055
1056         Timer *t = data;
1057         usec_t u;
1058         int r;
1059         TimerValue *v;
1060         TimerBase b;
1061
1062         assert(filename);
1063         assert(lvalue);
1064         assert(rvalue);
1065         assert(data);
1066
1067         if ((b = timer_base_from_string(lvalue)) < 0) {
1068                 log_error("[%s:%u] Failed to parse timer base: %s", filename, line, lvalue);
1069                 return -EINVAL;
1070         }
1071
1072         if ((r = parse_usec(rvalue, &u)) < 0) {
1073                 log_error("[%s:%u] Failed to parse timer value: %s", filename, line, rvalue);
1074                 return r;
1075         }
1076
1077         if (!(v = new0(TimerValue, 1)))
1078                 return -ENOMEM;
1079
1080         v->base = b;
1081         v->value = u;
1082
1083         LIST_PREPEND(TimerValue, value, t->values, v);
1084
1085         return 0;
1086 }
1087
1088 static int config_parse_timer_unit(
1089                 const char *filename,
1090                 unsigned line,
1091                 const char *section,
1092                 const char *lvalue,
1093                 const char *rvalue,
1094                 void *data,
1095                 void *userdata) {
1096
1097         Timer *t = data;
1098         int r;
1099         DBusError error;
1100
1101         assert(filename);
1102         assert(lvalue);
1103         assert(rvalue);
1104         assert(data);
1105
1106         dbus_error_init(&error);
1107
1108         if (endswith(rvalue, ".timer")) {
1109                 log_error("[%s:%u] Unit cannot be of type timer: %s", filename, line, rvalue);
1110                 return -EINVAL;
1111         }
1112
1113         if ((r = manager_load_unit(t->meta.manager, rvalue, NULL, NULL, &t->unit)) < 0) {
1114                 log_error("[%s:%u] Failed to load unit %s: %s", filename, line, rvalue, bus_error(&error, r));
1115                 dbus_error_free(&error);
1116                 return r;
1117         }
1118
1119         return 0;
1120 }
1121
1122 static int config_parse_path_spec(
1123                 const char *filename,
1124                 unsigned line,
1125                 const char *section,
1126                 const char *lvalue,
1127                 const char *rvalue,
1128                 void *data,
1129                 void *userdata) {
1130
1131         Path *p = data;
1132         PathSpec *s;
1133         PathType b;
1134
1135         assert(filename);
1136         assert(lvalue);
1137         assert(rvalue);
1138         assert(data);
1139
1140         if ((b = path_type_from_string(lvalue)) < 0) {
1141                 log_error("[%s:%u] Failed to parse path type: %s", filename, line, lvalue);
1142                 return -EINVAL;
1143         }
1144
1145         if (!path_is_absolute(rvalue)) {
1146                 log_error("[%s:%u] Path is not absolute: %s", filename, line, rvalue);
1147                 return -EINVAL;
1148         }
1149
1150         if (!(s = new0(PathSpec, 1)))
1151                 return -ENOMEM;
1152
1153         if (!(s->path = strdup(rvalue))) {
1154                 free(s);
1155                 return -ENOMEM;
1156         }
1157
1158         path_kill_slashes(s->path);
1159
1160         s->type = b;
1161         s->inotify_fd = -1;
1162
1163         LIST_PREPEND(PathSpec, spec, p->specs, s);
1164
1165         return 0;
1166 }
1167
1168 static int config_parse_path_unit(
1169                 const char *filename,
1170                 unsigned line,
1171                 const char *section,
1172                 const char *lvalue,
1173                 const char *rvalue,
1174                 void *data,
1175                 void *userdata) {
1176
1177         Path *t = data;
1178         int r;
1179         DBusError error;
1180
1181         assert(filename);
1182         assert(lvalue);
1183         assert(rvalue);
1184         assert(data);
1185
1186         dbus_error_init(&error);
1187
1188         if (endswith(rvalue, ".path")) {
1189                 log_error("[%s:%u] Unit cannot be of type path: %s", filename, line, rvalue);
1190                 return -EINVAL;
1191         }
1192
1193         if ((r = manager_load_unit(t->meta.manager, rvalue, NULL, &error, &t->unit)) < 0) {
1194                 log_error("[%s:%u] Failed to load unit %s: %s", filename, line, rvalue, bus_error(&error, r));
1195                 dbus_error_free(&error);
1196                 return r;
1197         }
1198
1199         return 0;
1200 }
1201
1202 static int config_parse_env_file(
1203                 const char *filename,
1204                 unsigned line,
1205                 const char *section,
1206                 const char *lvalue,
1207                 const char *rvalue,
1208                 void *data,
1209                 void *userdata) {
1210
1211         FILE *f;
1212         int r;
1213         char ***env = data;
1214
1215         assert(filename);
1216         assert(lvalue);
1217         assert(rvalue);
1218         assert(data);
1219
1220         if (!(f = fopen(rvalue, "re"))) {
1221                 log_error("[%s:%u] Failed to open environment file '%s': %m", filename, line, rvalue);
1222                 return -errno;
1223         }
1224
1225         while (!feof(f)) {
1226                 char l[LINE_MAX], *p;
1227                 char **t;
1228
1229                 if (!fgets(l, sizeof(l), f)) {
1230                         if (feof(f))
1231                                 break;
1232
1233                         r = -errno;
1234                         log_error("[%s:%u] Failed to read environment file '%s': %m", filename, line, rvalue);
1235                         goto finish;
1236                 }
1237
1238                 p = strstrip(l);
1239
1240                 if (!*p)
1241                         continue;
1242
1243                 if (strchr(COMMENTS, *p))
1244                         continue;
1245
1246                 t = strv_env_set(*env, p);
1247                 strv_free(*env);
1248                 *env = t;
1249         }
1250
1251         r = 0;
1252
1253 finish:
1254         if (f)
1255                 fclose(f);
1256
1257         return r;
1258 }
1259
1260 static int config_parse_ip_tos(
1261                 const char *filename,
1262                 unsigned line,
1263                 const char *section,
1264                 const char *lvalue,
1265                 const char *rvalue,
1266                 void *data,
1267                 void *userdata) {
1268
1269         int *ip_tos = data, x;
1270         int r;
1271
1272         assert(filename);
1273         assert(lvalue);
1274         assert(rvalue);
1275         assert(data);
1276
1277         if ((x = ip_tos_from_string(rvalue)) < 0)
1278                 if ((r = safe_atoi(rvalue, &x)) < 0) {
1279                         log_error("[%s:%u] Failed to parse IP TOS value: %s", filename, line, rvalue);
1280                         return r;
1281                 }
1282
1283         *ip_tos = x;
1284         return 0;
1285 }
1286
1287 static DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier");
1288
1289 #define FOLLOW_MAX 8
1290
1291 static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
1292         unsigned c = 0;
1293         int fd, r;
1294         FILE *f;
1295         char *id = NULL;
1296
1297         assert(filename);
1298         assert(*filename);
1299         assert(_f);
1300         assert(names);
1301
1302         /* This will update the filename pointer if the loaded file is
1303          * reached by a symlink. The old string will be freed. */
1304
1305         for (;;) {
1306                 char *target, *name;
1307
1308                 if (c++ >= FOLLOW_MAX)
1309                         return -ELOOP;
1310
1311                 path_kill_slashes(*filename);
1312
1313                 /* Add the file name we are currently looking at to
1314                  * the names of this unit */
1315                 name = file_name_from_path(*filename);
1316                 if (!(id = set_get(names, name))) {
1317
1318                         if (!(id = strdup(name)))
1319                                 return -ENOMEM;
1320
1321                         if ((r = set_put(names, id)) < 0) {
1322                                 free(id);
1323                                 return r;
1324                         }
1325                 }
1326
1327                 /* Try to open the file name, but don't if its a symlink */
1328                 if ((fd = open(*filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW)) >= 0)
1329                         break;
1330
1331                 if (errno != ELOOP)
1332                         return -errno;
1333
1334                 /* Hmm, so this is a symlink. Let's read the name, and follow it manually */
1335                 if ((r = readlink_and_make_absolute(*filename, &target)) < 0)
1336                         return r;
1337
1338                 free(*filename);
1339                 *filename = target;
1340         }
1341
1342         if (!(f = fdopen(fd, "r"))) {
1343                 r = -errno;
1344                 close_nointr_nofail(fd);
1345                 return r;
1346         }
1347
1348         *_f = f;
1349         *_final = id;
1350         return 0;
1351 }
1352
1353 static int merge_by_names(Unit **u, Set *names, const char *id) {
1354         char *k;
1355         int r;
1356
1357         assert(u);
1358         assert(*u);
1359         assert(names);
1360
1361         /* Let's try to add in all symlink names we found */
1362         while ((k = set_steal_first(names))) {
1363
1364                 /* First try to merge in the other name into our
1365                  * unit */
1366                 if ((r = unit_merge_by_name(*u, k)) < 0) {
1367                         Unit *other;
1368
1369                         /* Hmm, we couldn't merge the other unit into
1370                          * ours? Then let's try it the other way
1371                          * round */
1372
1373                         other = manager_get_unit((*u)->meta.manager, k);
1374                         free(k);
1375
1376                         if (other)
1377                                 if ((r = unit_merge(other, *u)) >= 0) {
1378                                         *u = other;
1379                                         return merge_by_names(u, names, NULL);
1380                                 }
1381
1382                         return r;
1383                 }
1384
1385                 if (id == k)
1386                         unit_choose_id(*u, id);
1387
1388                 free(k);
1389         }
1390
1391         return 0;
1392 }
1393
1394 static void dump_items(FILE *f, const ConfigItem *items) {
1395         const ConfigItem *i;
1396         const char *prev_section = NULL;
1397         bool not_first = false;
1398
1399         struct {
1400                 ConfigParserCallback callback;
1401                 const char *rvalue;
1402         } table[] = {
1403                 { config_parse_int,              "INTEGER" },
1404                 { config_parse_unsigned,         "UNSIGNED" },
1405                 { config_parse_size,             "SIZE" },
1406                 { config_parse_bool,             "BOOLEAN" },
1407                 { config_parse_string,           "STRING" },
1408                 { config_parse_path,             "PATH" },
1409                 { config_parse_strv,             "STRING [...]" },
1410                 { config_parse_nice,             "NICE" },
1411                 { config_parse_oom_adjust,       "OOMADJUST" },
1412                 { config_parse_io_class,         "IOCLASS" },
1413                 { config_parse_io_priority,      "IOPRIORITY" },
1414                 { config_parse_cpu_sched_policy, "CPUSCHEDPOLICY" },
1415                 { config_parse_cpu_sched_prio,   "CPUSCHEDPRIO" },
1416                 { config_parse_cpu_affinity,     "CPUAFFINITY" },
1417                 { config_parse_mode,             "MODE" },
1418                 { config_parse_env_file,         "FILE" },
1419                 { config_parse_output,           "OUTPUT" },
1420                 { config_parse_input,            "INPUT" },
1421                 { config_parse_facility,         "FACILITY" },
1422                 { config_parse_level,            "LEVEL" },
1423                 { config_parse_capabilities,     "CAPABILITIES" },
1424                 { config_parse_secure_bits,      "SECUREBITS" },
1425                 { config_parse_bounding_set,     "BOUNDINGSET" },
1426                 { config_parse_timer_slack_nsec, "TIMERSLACK" },
1427                 { config_parse_limit,            "LIMIT" },
1428                 { config_parse_cgroup,           "CGROUP [...]" },
1429                 { config_parse_deps,             "UNIT [...]" },
1430                 { config_parse_names,            "UNIT [...]" },
1431                 { config_parse_exec,             "PATH [ARGUMENT [...]]" },
1432                 { config_parse_service_type,     "SERVICETYPE" },
1433                 { config_parse_service_restart,  "SERVICERESTART" },
1434                 { config_parse_sysv_priority,    "SYSVPRIORITY" },
1435                 { config_parse_kill_mode,        "KILLMODE" },
1436                 { config_parse_kill_signal,      "SIGNAL" },
1437                 { config_parse_listen,           "SOCKET [...]" },
1438                 { config_parse_socket_bind,      "SOCKETBIND" },
1439                 { config_parse_bindtodevice,     "NETWORKINTERFACE" },
1440                 { config_parse_usec,             "SECONDS" },
1441                 { config_parse_path_strv,        "PATH [...]" },
1442                 { config_parse_mount_flags,      "MOUNTFLAG [...]" },
1443                 { config_parse_string_printf,    "STRING" },
1444                 { config_parse_timer,            "TIMER" },
1445                 { config_parse_timer_unit,       "NAME" },
1446                 { config_parse_path_spec,        "PATH" },
1447                 { config_parse_path_unit,        "UNIT" },
1448                 { config_parse_notify_access,    "ACCESS" },
1449                 { config_parse_ip_tos,           "TOS" },
1450         };
1451
1452         assert(f);
1453         assert(items);
1454
1455         for (i = items; i->lvalue; i++) {
1456                 unsigned j;
1457                 const char *rvalue = "OTHER";
1458
1459                 if (!streq_ptr(i->section, prev_section)) {
1460                         if (!not_first)
1461                                 not_first = true;
1462                         else
1463                                 fputc('\n', f);
1464
1465                         fprintf(f, "[%s]\n", i->section);
1466                         prev_section = i->section;
1467                 }
1468
1469                 for (j = 0; j < ELEMENTSOF(table); j++)
1470                         if (i->parse == table[j].callback) {
1471                                 rvalue = table[j].rvalue;
1472                                 break;
1473                         }
1474
1475                 fprintf(f, "%s=%s\n", i->lvalue, rvalue);
1476         }
1477 }
1478
1479 static int load_from_path(Unit *u, const char *path) {
1480
1481         static const char* const section_table[_UNIT_TYPE_MAX] = {
1482                 [UNIT_SERVICE]   = "Service",
1483                 [UNIT_TIMER]     = "Timer",
1484                 [UNIT_SOCKET]    = "Socket",
1485                 [UNIT_TARGET]    = "Target",
1486                 [UNIT_DEVICE]    = "Device",
1487                 [UNIT_MOUNT]     = "Mount",
1488                 [UNIT_AUTOMOUNT] = "Automount",
1489                 [UNIT_SNAPSHOT]  = "Snapshot",
1490                 [UNIT_SWAP]      = "Swap",
1491                 [UNIT_PATH]      = "Path"
1492         };
1493
1494 #define EXEC_CONTEXT_CONFIG_ITEMS(context, section) \
1495                 { "WorkingDirectory",       config_parse_path,            &(context).working_directory,                    section   }, \
1496                 { "RootDirectory",          config_parse_path,            &(context).root_directory,                       section   }, \
1497                 { "User",                   config_parse_string_printf,   &(context).user,                                 section   }, \
1498                 { "Group",                  config_parse_string_printf,   &(context).group,                                section   }, \
1499                 { "SupplementaryGroups",    config_parse_strv,            &(context).supplementary_groups,                 section   }, \
1500                 { "Nice",                   config_parse_nice,            &(context),                                      section   }, \
1501                 { "OOMAdjust",              config_parse_oom_adjust,      &(context),                                      section   }, \
1502                 { "IOSchedulingClass",      config_parse_io_class,        &(context),                                      section   }, \
1503                 { "IOSchedulingPriority",   config_parse_io_priority,     &(context),                                      section   }, \
1504                 { "CPUSchedulingPolicy",    config_parse_cpu_sched_policy,&(context),                                      section   }, \
1505                 { "CPUSchedulingPriority",  config_parse_cpu_sched_prio,  &(context),                                      section   }, \
1506                 { "CPUSchedulingResetOnFork", config_parse_bool,          &(context).cpu_sched_reset_on_fork,              section   }, \
1507                 { "CPUAffinity",            config_parse_cpu_affinity,    &(context),                                      section   }, \
1508                 { "UMask",                  config_parse_mode,            &(context).umask,                                section   }, \
1509                 { "Environment",            config_parse_strv,            &(context).environment,                          section   }, \
1510                 { "EnvironmentFile",        config_parse_env_file,        &(context).environment,                          section   }, \
1511                 { "StandardInput",          config_parse_input,           &(context).std_input,                            section   }, \
1512                 { "StandardOutput",         config_parse_output,          &(context).std_output,                           section   }, \
1513                 { "StandardError",          config_parse_output,          &(context).std_error,                            section   }, \
1514                 { "TTYPath",                config_parse_path,            &(context).tty_path,                             section   }, \
1515                 { "SyslogIdentifier",       config_parse_string_printf,   &(context).syslog_identifier,                    section   }, \
1516                 { "SyslogFacility",         config_parse_facility,        &(context).syslog_priority,                      section   }, \
1517                 { "SyslogLevel",            config_parse_level,           &(context).syslog_priority,                      section   }, \
1518                 { "SyslogLevelPrefix",      config_parse_bool,            &(context).syslog_level_prefix,                  section   }, \
1519                 { "Capabilities",           config_parse_capabilities,    &(context),                                      section   }, \
1520                 { "SecureBits",             config_parse_secure_bits,     &(context),                                      section   }, \
1521                 { "CapabilityBoundingSetDrop", config_parse_bounding_set, &(context),                                      section   }, \
1522                 { "TimerSlackNSec",         config_parse_timer_slack_nsec,&(context),                                      section   }, \
1523                 { "LimitCPU",               config_parse_limit,           &(context).rlimit[RLIMIT_CPU],                   section   }, \
1524                 { "LimitFSIZE",             config_parse_limit,           &(context).rlimit[RLIMIT_FSIZE],                 section   }, \
1525                 { "LimitDATA",              config_parse_limit,           &(context).rlimit[RLIMIT_DATA],                  section   }, \
1526                 { "LimitSTACK",             config_parse_limit,           &(context).rlimit[RLIMIT_STACK],                 section   }, \
1527                 { "LimitCORE",              config_parse_limit,           &(context).rlimit[RLIMIT_CORE],                  section   }, \
1528                 { "LimitRSS",               config_parse_limit,           &(context).rlimit[RLIMIT_RSS],                   section   }, \
1529                 { "LimitNOFILE",            config_parse_limit,           &(context).rlimit[RLIMIT_NOFILE],                section   }, \
1530                 { "LimitAS",                config_parse_limit,           &(context).rlimit[RLIMIT_AS],                    section   }, \
1531                 { "LimitNPROC",             config_parse_limit,           &(context).rlimit[RLIMIT_NPROC],                 section   }, \
1532                 { "LimitMEMLOCK",           config_parse_limit,           &(context).rlimit[RLIMIT_MEMLOCK],               section   }, \
1533                 { "LimitLOCKS",             config_parse_limit,           &(context).rlimit[RLIMIT_LOCKS],                 section   }, \
1534                 { "LimitSIGPENDING",        config_parse_limit,           &(context).rlimit[RLIMIT_SIGPENDING],            section   }, \
1535                 { "LimitMSGQUEUE",          config_parse_limit,           &(context).rlimit[RLIMIT_MSGQUEUE],              section   }, \
1536                 { "LimitNICE",              config_parse_limit,           &(context).rlimit[RLIMIT_NICE],                  section   }, \
1537                 { "LimitRTPRIO",            config_parse_limit,           &(context).rlimit[RLIMIT_RTPRIO],                section   }, \
1538                 { "LimitRTTIME",            config_parse_limit,           &(context).rlimit[RLIMIT_RTTIME],                section   }, \
1539                 { "ControlGroup",           config_parse_cgroup,          u,                                               section   }, \
1540                 { "ReadWriteDirectories",   config_parse_path_strv,       &(context).read_write_dirs,                      section   }, \
1541                 { "ReadOnlyDirectories",    config_parse_path_strv,       &(context).read_only_dirs,                       section   }, \
1542                 { "InaccessibleDirectories",config_parse_path_strv,       &(context).inaccessible_dirs,                    section   }, \
1543                 { "PrivateTmp",             config_parse_bool,            &(context).private_tmp,                          section   }, \
1544                 { "MountFlags",             config_parse_mount_flags,     &(context),                                      section   }, \
1545                 { "TCPWrapName",            config_parse_string_printf,   &(context).tcpwrap_name,                         section   }, \
1546                 { "PAMName",                config_parse_string_printf,   &(context).pam_name,                             section   }, \
1547                 { "KillMode",               config_parse_kill_mode,       &(context).kill_mode,                            section   }, \
1548                 { "KillSignal",             config_parse_kill_signal,     &(context).kill_signal,                          section   }
1549
1550         const ConfigItem items[] = {
1551                 { "Names",                  config_parse_names,           u,                                               "Unit"    },
1552                 { "Description",            config_parse_string_printf,   &u->meta.description,                            "Unit"    },
1553                 { "Requires",               config_parse_deps,            UINT_TO_PTR(UNIT_REQUIRES),                      "Unit"    },
1554                 { "RequiresOverridable",    config_parse_deps,            UINT_TO_PTR(UNIT_REQUIRES_OVERRIDABLE),          "Unit"    },
1555                 { "Requisite",              config_parse_deps,            UINT_TO_PTR(UNIT_REQUISITE),                     "Unit"    },
1556                 { "RequisiteOverridable",   config_parse_deps,            UINT_TO_PTR(UNIT_REQUISITE_OVERRIDABLE),         "Unit"    },
1557                 { "Wants",                  config_parse_deps,            UINT_TO_PTR(UNIT_WANTS),                         "Unit"    },
1558                 { "Conflicts",              config_parse_deps,            UINT_TO_PTR(UNIT_CONFLICTS),                     "Unit"    },
1559                 { "Before",                 config_parse_deps,            UINT_TO_PTR(UNIT_BEFORE),                        "Unit"    },
1560                 { "After",                  config_parse_deps,            UINT_TO_PTR(UNIT_AFTER),                         "Unit"    },
1561                 { "RecursiveStop",          config_parse_bool,            &u->meta.recursive_stop,                         "Unit"    },
1562                 { "StopWhenUnneeded",       config_parse_bool,            &u->meta.stop_when_unneeded,                     "Unit"    },
1563                 { "OnlyByDependency",       config_parse_bool,            &u->meta.only_by_dependency,                     "Unit"    },
1564                 { "DefaultDependencies",    config_parse_bool,            &u->meta.default_dependencies,                   "Unit"    },
1565
1566                 { "PIDFile",                config_parse_path,            &u->service.pid_file,                            "Service" },
1567                 { "ExecStartPre",           config_parse_exec,            u->service.exec_command+SERVICE_EXEC_START_PRE,  "Service" },
1568                 { "ExecStart",              config_parse_exec,            u->service.exec_command+SERVICE_EXEC_START,      "Service" },
1569                 { "ExecStartPost",          config_parse_exec,            u->service.exec_command+SERVICE_EXEC_START_POST, "Service" },
1570                 { "ExecReload",             config_parse_exec,            u->service.exec_command+SERVICE_EXEC_RELOAD,     "Service" },
1571                 { "ExecStop",               config_parse_exec,            u->service.exec_command+SERVICE_EXEC_STOP,       "Service" },
1572                 { "ExecStopPost",           config_parse_exec,            u->service.exec_command+SERVICE_EXEC_STOP_POST,  "Service" },
1573                 { "RestartSec",             config_parse_usec,            &u->service.restart_usec,                        "Service" },
1574                 { "TimeoutSec",             config_parse_usec,            &u->service.timeout_usec,                        "Service" },
1575                 { "Type",                   config_parse_service_type,    &u->service.type,                                "Service" },
1576                 { "Restart",                config_parse_service_restart, &u->service.restart,                             "Service" },
1577                 { "PermissionsStartOnly",   config_parse_bool,            &u->service.permissions_start_only,              "Service" },
1578                 { "RootDirectoryStartOnly", config_parse_bool,            &u->service.root_directory_start_only,           "Service" },
1579                 { "ValidNoProcess",         config_parse_bool,            &u->service.valid_no_process,                    "Service" },
1580                 { "SysVStartPriority",      config_parse_sysv_priority,   &u->service.sysv_start_priority,                 "Service" },
1581                 { "NonBlocking",            config_parse_bool,            &u->service.exec_context.non_blocking,           "Service" },
1582                 { "BusName",                config_parse_string_printf,   &u->service.bus_name,                            "Service" },
1583                 { "NotifyAccess",           config_parse_notify_access,   &u->service.notify_access,                       "Service" },
1584                 EXEC_CONTEXT_CONFIG_ITEMS(u->service.exec_context, "Service"),
1585
1586                 { "ListenStream",           config_parse_listen,          &u->socket,                                      "Socket"  },
1587                 { "ListenDatagram",         config_parse_listen,          &u->socket,                                      "Socket"  },
1588                 { "ListenSequentialPacket", config_parse_listen,          &u->socket,                                      "Socket"  },
1589                 { "ListenFIFO",             config_parse_listen,          &u->socket,                                      "Socket"  },
1590                 { "BindIPv6Only",           config_parse_socket_bind,     &u->socket,                                      "Socket"  },
1591                 { "Backlog",                config_parse_unsigned,        &u->socket.backlog,                              "Socket"  },
1592                 { "BindToDevice",           config_parse_bindtodevice,    &u->socket,                                      "Socket"  },
1593                 { "ExecStartPre",           config_parse_exec,            u->socket.exec_command+SOCKET_EXEC_START_PRE,    "Socket"  },
1594                 { "ExecStartPost",          config_parse_exec,            u->socket.exec_command+SOCKET_EXEC_START_POST,   "Socket"  },
1595                 { "ExecStopPre",            config_parse_exec,            u->socket.exec_command+SOCKET_EXEC_STOP_PRE,     "Socket"  },
1596                 { "ExecStopPost",           config_parse_exec,            u->socket.exec_command+SOCKET_EXEC_STOP_POST,    "Socket"  },
1597                 { "TimeoutSec",             config_parse_usec,            &u->socket.timeout_usec,                         "Socket"  },
1598                 { "DirectoryMode",          config_parse_mode,            &u->socket.directory_mode,                       "Socket"  },
1599                 { "SocketMode",             config_parse_mode,            &u->socket.socket_mode,                          "Socket"  },
1600                 { "Accept",                 config_parse_bool,            &u->socket.accept,                               "Socket"  },
1601                 { "MaxConnections",         config_parse_unsigned,        &u->socket.max_connections,                      "Socket"  },
1602                 { "KeepAlive",              config_parse_bool,            &u->socket.keep_alive,                           "Socket"  },
1603                 { "Priority",               config_parse_int,             &u->socket.priority,                             "Socket"  },
1604                 { "ReceiveBuffer",          config_parse_size,            &u->socket.receive_buffer,                       "Socket"  },
1605                 { "SendBuffer",             config_parse_size,            &u->socket.send_buffer,                          "Socket"  },
1606                 { "IPTOS",                  config_parse_ip_tos,          &u->socket.ip_tos,                               "Socket"  },
1607                 { "IPTTL",                  config_parse_int,             &u->socket.ip_ttl,                               "Socket"  },
1608                 { "Mark",                   config_parse_int,             &u->socket.mark,                                 "Socket"  },
1609                 { "PipeSize",               config_parse_size,            &u->socket.pipe_size,                            "Socket"  },
1610                 { "FreeBind",               config_parse_bool,            &u->socket.free_bind,                            "Socket"  },
1611                 EXEC_CONTEXT_CONFIG_ITEMS(u->socket.exec_context, "Socket"),
1612
1613                 { "What",                   config_parse_string,          &u->mount.parameters_fragment.what,              "Mount"   },
1614                 { "Where",                  config_parse_path,            &u->mount.where,                                 "Mount"   },
1615                 { "Options",                config_parse_string,          &u->mount.parameters_fragment.options,           "Mount"   },
1616                 { "Type",                   config_parse_string,          &u->mount.parameters_fragment.fstype,            "Mount"   },
1617                 { "TimeoutSec",             config_parse_usec,            &u->mount.timeout_usec,                          "Mount"   },
1618                 { "DirectoryMode",          config_parse_mode,            &u->mount.directory_mode,                        "Mount"   },
1619                 EXEC_CONTEXT_CONFIG_ITEMS(u->mount.exec_context, "Mount"),
1620
1621                 { "Where",                  config_parse_path,            &u->automount.where,                             "Automount" },
1622                 { "DirectoryMode",          config_parse_mode,            &u->automount.directory_mode,                    "Automount" },
1623
1624                 { "What",                   config_parse_path,            &u->swap.parameters_fragment.what,               "Swap"    },
1625                 { "Priority",               config_parse_int,             &u->swap.parameters_fragment.priority,           "Swap"    },
1626
1627                 { "OnActiveSec",            config_parse_timer,           &u->timer,                                       "Timer"   },
1628                 { "OnBootSec",              config_parse_timer,           &u->timer,                                       "Timer"   },
1629                 { "OnStartupSec",           config_parse_timer,           &u->timer,                                       "Timer"   },
1630                 { "OnUnitActiveSec",        config_parse_timer,           &u->timer,                                       "Timer"   },
1631                 { "OnUnitInactiveSec",      config_parse_timer,           &u->timer,                                       "Timer"   },
1632                 { "Unit",                   config_parse_timer_unit,      &u->timer,                                       "Timer"   },
1633
1634                 { "PathExists",             config_parse_path_spec,       &u->path,                                        "Path"    },
1635                 { "PathChanged",            config_parse_path_spec,       &u->path,                                        "Path"    },
1636                 { "DirectoryNotEmpty",      config_parse_path_spec,       &u->path,                                        "Path"    },
1637                 { "Unit",                   config_parse_path_unit,       &u->path,                                        "Path"    },
1638
1639                 /* The [Install] section is ignored here. */
1640                 { "Alias",                  NULL,                         NULL,                                            "Install" },
1641                 { "WantedBy",               NULL,                         NULL,                                            "Install" },
1642                 { "Also",                   NULL,                         NULL,                                            "Install" },
1643
1644                 { NULL, NULL, NULL, NULL }
1645         };
1646
1647 #undef EXEC_CONTEXT_CONFIG_ITEMS
1648
1649         const char *sections[4];
1650         int r;
1651         Set *symlink_names;
1652         FILE *f = NULL;
1653         char *filename = NULL, *id = NULL;
1654         Unit *merged;
1655
1656         if (!u) {
1657                 /* Dirty dirty hack. */
1658                 dump_items((FILE*) path, items);
1659                 return 0;
1660         }
1661
1662         assert(u);
1663         assert(path);
1664
1665         sections[0] = "Unit";
1666         sections[1] = section_table[u->meta.type];
1667         sections[2] = "Install";
1668         sections[3] = NULL;
1669
1670         if (!(symlink_names = set_new(string_hash_func, string_compare_func)))
1671                 return -ENOMEM;
1672
1673         if (path_is_absolute(path)) {
1674
1675                 if (!(filename = strdup(path))) {
1676                         r = -ENOMEM;
1677                         goto finish;
1678                 }
1679
1680                 if ((r = open_follow(&filename, &f, symlink_names, &id)) < 0) {
1681                         free(filename);
1682                         filename = NULL;
1683
1684                         if (r != -ENOENT)
1685                                 goto finish;
1686                 }
1687
1688         } else  {
1689                 char **p;
1690
1691                 STRV_FOREACH(p, u->meta.manager->lookup_paths.unit_path) {
1692
1693                         /* Instead of opening the path right away, we manually
1694                          * follow all symlinks and add their name to our unit
1695                          * name set while doing so */
1696                         if (!(filename = path_make_absolute(path, *p))) {
1697                                 r = -ENOMEM;
1698                                 goto finish;
1699                         }
1700
1701                         if (u->meta.manager->unit_path_cache &&
1702                             !set_get(u->meta.manager->unit_path_cache, filename))
1703                                 r = -ENOENT;
1704                         else
1705                                 r = open_follow(&filename, &f, symlink_names, &id);
1706
1707                         if (r < 0) {
1708                                 char *sn;
1709
1710                                 free(filename);
1711                                 filename = NULL;
1712
1713                                 if (r != -ENOENT)
1714                                         goto finish;
1715
1716                                 /* Empty the symlink names for the next run */
1717                                 while ((sn = set_steal_first(symlink_names)))
1718                                         free(sn);
1719
1720                                 continue;
1721                         }
1722
1723                         break;
1724                 }
1725         }
1726
1727         if (!filename) {
1728                 r = 0;
1729                 goto finish;
1730         }
1731
1732         merged = u;
1733         if ((r = merge_by_names(&merged, symlink_names, id)) < 0)
1734                 goto finish;
1735
1736         if (merged != u) {
1737                 u->meta.load_state = UNIT_MERGED;
1738                 r = 0;
1739                 goto finish;
1740         }
1741
1742         /* Now, parse the file contents */
1743         if ((r = config_parse(filename, f, sections, items, false, u)) < 0)
1744                 goto finish;
1745
1746         free(u->meta.fragment_path);
1747         u->meta.fragment_path = filename;
1748         filename = NULL;
1749
1750         u->meta.load_state = UNIT_LOADED;
1751         r = 0;
1752
1753 finish:
1754         set_free_free(symlink_names);
1755         free(filename);
1756
1757         if (f)
1758                 fclose(f);
1759
1760         return r;
1761 }
1762
1763 int unit_load_fragment(Unit *u) {
1764         int r;
1765
1766         assert(u);
1767
1768         if (u->meta.fragment_path) {
1769
1770                 if ((r = load_from_path(u, u->meta.fragment_path)) < 0)
1771                         return r;
1772
1773         } else {
1774                 Iterator i;
1775                 const char *t;
1776
1777                 /* Try to find the unit under its id */
1778                 if ((r = load_from_path(u, u->meta.id)) < 0)
1779                         return r;
1780
1781                 /* Try to find an alias we can load this with */
1782                 if (u->meta.load_state == UNIT_STUB)
1783                         SET_FOREACH(t, u->meta.names, i) {
1784
1785                                 if (t == u->meta.id)
1786                                         continue;
1787
1788                                 if ((r = load_from_path(u, t)) < 0)
1789                                         return r;
1790
1791                                 if (u->meta.load_state != UNIT_STUB)
1792                                         break;
1793                         }
1794
1795                 /* Now, follow the same logic, but look for a template */
1796                 if (u->meta.load_state == UNIT_STUB && u->meta.instance) {
1797                         char *k;
1798
1799                         if (!(k = unit_name_template(u->meta.id)))
1800                                 return -ENOMEM;
1801
1802                         r = load_from_path(u, k);
1803                         free(k);
1804
1805                         if (r < 0)
1806                                 return r;
1807
1808                         if (u->meta.load_state == UNIT_STUB)
1809                                 SET_FOREACH(t, u->meta.names, i) {
1810
1811                                         if (t == u->meta.id)
1812                                                 continue;
1813
1814                                         if (!(k = unit_name_template(t)))
1815                                                 return -ENOMEM;
1816
1817                                         r = load_from_path(u, k);
1818                                         free(k);
1819
1820                                         if (r < 0)
1821                                                 return r;
1822
1823                                         if (u->meta.load_state != UNIT_STUB)
1824                                                 break;
1825                                 }
1826                 }
1827         }
1828
1829         return 0;
1830 }
1831
1832 void unit_dump_config_items(FILE *f) {
1833         /* OK, this wins a prize for extreme ugliness. */
1834
1835         load_from_path(NULL, (const void*) f);
1836 }