chiark / gitweb /
unit: refuse merging if the unit in question has a job assigned or suchlike
[elogind.git] / 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
31 #include "unit.h"
32 #include "strv.h"
33 #include "conf-parser.h"
34 #include "load-fragment.h"
35 #include "log.h"
36 #include "ioprio.h"
37 #include "securebits.h"
38 #include "missing.h"
39
40 static int config_parse_deps(
41                 const char *filename,
42                 unsigned line,
43                 const char *section,
44                 const char *lvalue,
45                 const char *rvalue,
46                 void *data,
47                 void *userdata) {
48
49         UnitDependency d = PTR_TO_UINT(data);
50         Unit *u = userdata;
51         char *w;
52         size_t l;
53         char *state;
54
55         assert(filename);
56         assert(lvalue);
57         assert(rvalue);
58
59         FOREACH_WORD(w, l, rvalue, state) {
60                 char *t;
61                 int r;
62
63                 if (!(t = strndup(w, l)))
64                         return -ENOMEM;
65
66                 r = unit_add_dependency_by_name(u, d, t);
67                 free(t);
68
69                 if (r < 0)
70                         return r;
71         }
72
73         return 0;
74 }
75
76 static int config_parse_names(
77                 const char *filename,
78                 unsigned line,
79                 const char *section,
80                 const char *lvalue,
81                 const char *rvalue,
82                 void *data,
83                 void *userdata) {
84
85         Unit *u = userdata;
86         char *w;
87         size_t l;
88         char *state;
89
90         assert(filename);
91         assert(lvalue);
92         assert(rvalue);
93         assert(data);
94
95         FOREACH_WORD(w, l, rvalue, state) {
96                 char *t;
97                 int r;
98
99                 if (!(t = strndup(w, l)))
100                         return -ENOMEM;
101
102                 r = unit_merge_by_name(u, t);
103                 free(t);
104
105                 if (r < 0)
106                         return r;
107         }
108
109         return 0;
110 }
111
112 static int config_parse_listen(
113                 const char *filename,
114                 unsigned line,
115                 const char *section,
116                 const char *lvalue,
117                 const char *rvalue,
118                 void *data,
119                 void *userdata) {
120
121         int r;
122         SocketPort *p;
123         Socket *s;
124
125         assert(filename);
126         assert(lvalue);
127         assert(rvalue);
128         assert(data);
129
130         s = (Socket*) data;
131
132         if (!(p = new0(SocketPort, 1)))
133                 return -ENOMEM;
134
135         if (streq(lvalue, "ListenFIFO")) {
136                 p->type = SOCKET_FIFO;
137
138                 if (!(p->path = strdup(rvalue))) {
139                         free(p);
140                         return -ENOMEM;
141                 }
142         } else {
143                 p->type = SOCKET_SOCKET;
144
145                 if ((r = socket_address_parse(&p->address, rvalue)) < 0) {
146                         log_error("[%s:%u] Failed to parse address value: %s", filename, line, rvalue);
147                         free(p);
148                         return r;
149                 }
150
151                 if (streq(lvalue, "ListenStream"))
152                         p->address.type = SOCK_STREAM;
153                 else if (streq(lvalue, "ListenDatagram"))
154                         p->address.type = SOCK_DGRAM;
155                 else {
156                         assert(streq(lvalue, "ListenSequentialPacket"));
157                         p->address.type = SOCK_SEQPACKET;
158                 }
159
160                 if (socket_address_family(&p->address) != AF_LOCAL && p->address.type == SOCK_SEQPACKET) {
161                         free(p);
162                         return -EPROTONOSUPPORT;
163                 }
164         }
165
166         p->fd = -1;
167         LIST_PREPEND(SocketPort, port, s->ports, p);
168
169         return 0;
170 }
171
172 static int config_parse_socket_bind(
173                 const char *filename,
174                 unsigned line,
175                 const char *section,
176                 const char *lvalue,
177                 const char *rvalue,
178                 void *data,
179                 void *userdata) {
180
181         int r;
182         Socket *s;
183
184         assert(filename);
185         assert(lvalue);
186         assert(rvalue);
187         assert(data);
188
189         s = (Socket*) data;
190
191         if ((r = parse_boolean(rvalue)) < 0) {
192                 log_error("[%s:%u] Failed to parse bind IPv6 only value: %s", filename, line, rvalue);
193                 return r;
194         }
195
196         s->bind_ipv6_only = r ? SOCKET_ADDRESS_IPV6_ONLY : SOCKET_ADDRESS_BOTH;
197
198         return 0;
199 }
200
201 static int config_parse_nice(
202                 const char *filename,
203                 unsigned line,
204                 const char *section,
205                 const char *lvalue,
206                 const char *rvalue,
207                 void *data,
208                 void *userdata) {
209
210         ExecContext *c = data;
211         int priority, r;
212
213         assert(filename);
214         assert(lvalue);
215         assert(rvalue);
216         assert(data);
217
218         if ((r = safe_atoi(rvalue, &priority)) < 0) {
219                 log_error("[%s:%u] Failed to parse nice priority: %s", filename, line, rvalue);
220                 return r;
221         }
222
223         if (priority < PRIO_MIN || priority >= PRIO_MAX) {
224                 log_error("[%s:%u] Nice priority out of range: %s", filename, line, rvalue);
225                 return -ERANGE;
226         }
227
228         c->nice = priority;
229         c->nice_set = false;
230
231         return 0;
232 }
233
234 static int config_parse_oom_adjust(
235                 const char *filename,
236                 unsigned line,
237                 const char *section,
238                 const char *lvalue,
239                 const char *rvalue,
240                 void *data,
241                 void *userdata) {
242
243         ExecContext *c = data;
244         int oa, r;
245
246         assert(filename);
247         assert(lvalue);
248         assert(rvalue);
249         assert(data);
250
251         if ((r = safe_atoi(rvalue, &oa)) < 0) {
252                 log_error("[%s:%u] Failed to parse OOM adjust value: %s", filename, line, rvalue);
253                 return r;
254         }
255
256         if (oa < OOM_DISABLE || oa > OOM_ADJUST_MAX) {
257                 log_error("[%s:%u] OOM adjust value out of range: %s", filename, line, rvalue);
258                 return -ERANGE;
259         }
260
261         c->oom_adjust = oa;
262         c->oom_adjust_set = true;
263
264         return 0;
265 }
266
267 static int config_parse_mode(
268                 const char *filename,
269                 unsigned line,
270                 const char *section,
271                 const char *lvalue,
272                 const char *rvalue,
273                 void *data,
274                 void *userdata) {
275
276         mode_t *m = data;
277         long l;
278         char *x = NULL;
279
280         assert(filename);
281         assert(lvalue);
282         assert(rvalue);
283         assert(data);
284
285         errno = 0;
286         l = strtol(rvalue, &x, 8);
287         if (!x || *x || errno) {
288                 log_error("[%s:%u] Failed to parse mode value: %s", filename, line, rvalue);
289                 return errno ? -errno : -EINVAL;
290         }
291
292         if (l < 0000 || l > 07777) {
293                 log_error("[%s:%u] mode value out of range: %s", filename, line, rvalue);
294                 return -ERANGE;
295         }
296
297         *m = (mode_t) l;
298         return 0;
299 }
300
301 static int config_parse_exec(
302                 const char *filename,
303                 unsigned line,
304                 const char *section,
305                 const char *lvalue,
306                 const char *rvalue,
307                 void *data,
308                 void *userdata) {
309
310         ExecCommand **e = data, *nce = NULL;
311         char **n;
312         char *w;
313         unsigned k;
314         size_t l;
315         char *state;
316
317         assert(filename);
318         assert(lvalue);
319         assert(rvalue);
320         assert(data);
321
322         k = 0;
323         FOREACH_WORD_QUOTED(w, l, rvalue, state)
324                 k++;
325
326         if (!(n = new(char*, k+1)))
327                 return -ENOMEM;
328
329         k = 0;
330         FOREACH_WORD_QUOTED(w, l, rvalue, state)
331                 if (!(n[k++] = strndup(w, l)))
332                         goto fail;
333
334         n[k] = NULL;
335
336         if (!n[0] || !path_is_absolute(n[0])) {
337                 log_error("[%s:%u] Invalid executable path in command line: %s", filename, line, rvalue);
338                 strv_free(n);
339                 return -EINVAL;
340         }
341
342         if (!(nce = new0(ExecCommand, 1)))
343                 goto fail;
344
345         nce->argv = n;
346         if (!(nce->path = strdup(n[0])))
347                 goto fail;
348
349         exec_command_append_list(e, nce);
350
351         return 0;
352
353 fail:
354         for (; k > 0; k--)
355                 free(n[k-1]);
356         free(n);
357
358         free(nce);
359
360         return -ENOMEM;
361 }
362
363 static int config_parse_usec(
364                 const char *filename,
365                 unsigned line,
366                 const char *section,
367                 const char *lvalue,
368                 const char *rvalue,
369                 void *data,
370                 void *userdata) {
371
372         usec_t *usec = data;
373         unsigned long long u;
374         int r;
375
376         assert(filename);
377         assert(lvalue);
378         assert(rvalue);
379         assert(data);
380
381         if ((r = safe_atollu(rvalue, &u)) < 0) {
382                 log_error("[%s:%u] Failed to parse time value: %s", filename, line, rvalue);
383                 return r;
384         }
385
386         /* We actually assume the user configures seconds. Later on we
387          * might choose to support suffixes for time values, to
388          * configure bigger or smaller units */
389
390         *usec = u * USEC_PER_SEC;
391
392         return 0;
393 }
394
395 static int config_parse_service_type(
396                 const char *filename,
397                 unsigned line,
398                 const char *section,
399                 const char *lvalue,
400                 const char *rvalue,
401                 void *data,
402                 void *userdata) {
403
404         Service *s = data;
405         ServiceType x;
406
407         assert(filename);
408         assert(lvalue);
409         assert(rvalue);
410         assert(data);
411
412         if ((x = service_type_from_string(rvalue)) < 0) {
413                 log_error("[%s:%u] Failed to parse service type: %s", filename, line, rvalue);
414                 return -EBADMSG;
415         }
416
417         s->type = x;
418
419         return 0;
420 }
421
422 static int config_parse_service_restart(
423                 const char *filename,
424                 unsigned line,
425                 const char *section,
426                 const char *lvalue,
427                 const char *rvalue,
428                 void *data,
429                 void *userdata) {
430
431         Service *s = data;
432         ServiceRestart x;
433
434         assert(filename);
435         assert(lvalue);
436         assert(rvalue);
437         assert(data);
438
439         if ((x = service_restart_from_string(rvalue)) < 0) {
440                 log_error("[%s:%u] Failed to parse service restart specifier: %s", filename, line, rvalue);
441                 return -EBADMSG;
442         }
443
444         s->restart = x;
445
446         return 0;
447 }
448
449 static int config_parse_bindtodevice(
450                 const char *filename,
451                 unsigned line,
452                 const char *section,
453                 const char *lvalue,
454                 const char *rvalue,
455                 void *data,
456                 void *userdata) {
457
458         Socket *s = data;
459         char *n;
460
461         assert(filename);
462         assert(lvalue);
463         assert(rvalue);
464         assert(data);
465
466         if (rvalue[0] && !streq(rvalue, "*")) {
467                 if (!(n = strdup(rvalue)))
468                         return -ENOMEM;
469         } else
470                 n = NULL;
471
472         free(s->bind_to_device);
473         s->bind_to_device = n;
474
475         return 0;
476 }
477
478 static int config_parse_output(
479                 const char *filename,
480                 unsigned line,
481                 const char *section,
482                 const char *lvalue,
483                 const char *rvalue,
484                 void *data,
485                 void *userdata) {
486
487         ExecOutput *o = data, x;
488
489         assert(filename);
490         assert(lvalue);
491         assert(rvalue);
492         assert(data);
493
494         if ((x = exec_output_from_string(rvalue)) < 0) {
495                 log_error("[%s:%u] Failed to parse output specifier: %s", filename, line, rvalue);
496                 return -EBADMSG;
497         }
498
499         *o = x;
500
501         return 0;
502 }
503
504 static int config_parse_input(
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         ExecInput *i = data, x;
514
515         assert(filename);
516         assert(lvalue);
517         assert(rvalue);
518         assert(data);
519
520         if ((x = exec_input_from_string(rvalue)) < 0) {
521                 log_error("[%s:%u] Failed to parse input specifier: %s", filename, line, rvalue);
522                 return -EBADMSG;
523         }
524
525         *i = x;
526
527         return 0;
528 }
529
530 static int config_parse_facility(
531                 const char *filename,
532                 unsigned line,
533                 const char *section,
534                 const char *lvalue,
535                 const char *rvalue,
536                 void *data,
537                 void *userdata) {
538
539
540         int *o = data, x;
541
542         assert(filename);
543         assert(lvalue);
544         assert(rvalue);
545         assert(data);
546
547         if ((x = log_facility_from_string(rvalue)) < 0)
548
549                 /* Second try, let's see if this is a number. */
550                 if (safe_atoi(rvalue, &x) < 0 || !log_facility_to_string(x)) {
551                         log_error("[%s:%u] Failed to parse log facility: %s", filename, line, rvalue);
552                         return -EBADMSG;
553                 }
554
555         *o = LOG_MAKEPRI(x, LOG_PRI(*o));
556
557         return 0;
558 }
559
560 static int config_parse_level(
561                 const char *filename,
562                 unsigned line,
563                 const char *section,
564                 const char *lvalue,
565                 const char *rvalue,
566                 void *data,
567                 void *userdata) {
568
569
570         int *o = data, x;
571
572         assert(filename);
573         assert(lvalue);
574         assert(rvalue);
575         assert(data);
576
577         if ((x = log_level_from_string(rvalue)) < 0)
578
579                 /* Second try, let's see if this is a number. */
580                 if (safe_atoi(rvalue, &x) < 0 || !log_level_to_string(x)) {
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
608                 /* Second try, let's see if this is a number. */
609                 if (safe_atoi(rvalue, &x) < 0 || !ioprio_class_to_string(x)) {
610                         log_error("[%s:%u] Failed to parse IO scheduling class: %s", filename, line, rvalue);
611                         return -EBADMSG;
612                 }
613
614         c->ioprio = IOPRIO_PRIO_VALUE(x, IOPRIO_PRIO_DATA(c->ioprio));
615         c->ioprio_set = true;
616
617         return 0;
618 }
619
620 static int config_parse_io_priority(
621                 const char *filename,
622                 unsigned line,
623                 const char *section,
624                 const char *lvalue,
625                 const char *rvalue,
626                 void *data,
627                 void *userdata) {
628
629         ExecContext *c = data;
630         int i;
631
632         assert(filename);
633         assert(lvalue);
634         assert(rvalue);
635         assert(data);
636
637         if (safe_atoi(rvalue, &i) < 0 || i < 0 || i >= IOPRIO_BE_NR) {
638                 log_error("[%s:%u] Failed to parse io priority: %s", filename, line, rvalue);
639                 return -EBADMSG;
640         }
641
642         c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), i);
643         c->ioprio_set = true;
644
645         return 0;
646 }
647
648 static int config_parse_cpu_sched_policy(
649                 const char *filename,
650                 unsigned line,
651                 const char *section,
652                 const char *lvalue,
653                 const char *rvalue,
654                 void *data,
655                 void *userdata) {
656
657
658         ExecContext *c = data;
659         int x;
660
661         assert(filename);
662         assert(lvalue);
663         assert(rvalue);
664         assert(data);
665
666         if ((x = sched_policy_from_string(rvalue)) < 0)
667
668                 /* Second try, let's see if this is a number. */
669                 if (safe_atoi(rvalue, &x) < 0 || !sched_policy_to_string(x)) {
670                         log_error("[%s:%u] Failed to parse CPU scheduling policy: %s", filename, line, rvalue);
671                         return -EBADMSG;
672                 }
673
674         c->cpu_sched_policy = x;
675         c->cpu_sched_set = true;
676
677         return 0;
678 }
679
680 static int config_parse_cpu_sched_prio(
681                 const char *filename,
682                 unsigned line,
683                 const char *section,
684                 const char *lvalue,
685                 const char *rvalue,
686                 void *data,
687                 void *userdata) {
688
689         ExecContext *c = data;
690         int i;
691
692         assert(filename);
693         assert(lvalue);
694         assert(rvalue);
695         assert(data);
696
697         /* On Linux RR/FIFO have the same range */
698         if (safe_atoi(rvalue, &i) < 0 || i < sched_get_priority_min(SCHED_RR) || i > sched_get_priority_max(SCHED_RR)) {
699                 log_error("[%s:%u] Failed to parse CPU scheduling priority: %s", filename, line, rvalue);
700                 return -EBADMSG;
701         }
702
703         c->cpu_sched_priority = i;
704         c->cpu_sched_set = true;
705
706         return 0;
707 }
708
709 static int config_parse_cpu_affinity(
710                 const char *filename,
711                 unsigned line,
712                 const char *section,
713                 const char *lvalue,
714                 const char *rvalue,
715                 void *data,
716                 void *userdata) {
717
718         ExecContext *c = data;
719         char *w;
720         size_t l;
721         char *state;
722
723         assert(filename);
724         assert(lvalue);
725         assert(rvalue);
726         assert(data);
727
728         FOREACH_WORD(w, l, rvalue, state) {
729                 char *t;
730                 int r;
731                 unsigned cpu;
732
733                 if (!(t = strndup(w, l)))
734                         return -ENOMEM;
735
736                 r = safe_atou(t, &cpu);
737                 free(t);
738
739                 if (r < 0 || cpu >= CPU_SETSIZE) {
740                         log_error("[%s:%u] Failed to parse CPU affinity: %s", filename, line, rvalue);
741                         return -EBADMSG;
742                 }
743
744                 CPU_SET(cpu, &c->cpu_affinity);
745         }
746
747         c->cpu_affinity_set = true;
748
749         return 0;
750 }
751
752 static int config_parse_capabilities(
753                 const char *filename,
754                 unsigned line,
755                 const char *section,
756                 const char *lvalue,
757                 const char *rvalue,
758                 void *data,
759                 void *userdata) {
760
761         ExecContext *c = data;
762         cap_t cap;
763
764         assert(filename);
765         assert(lvalue);
766         assert(rvalue);
767         assert(data);
768
769         if (!(cap = cap_from_text(rvalue))) {
770                 if (errno == ENOMEM)
771                         return -ENOMEM;
772
773                 log_error("[%s:%u] Failed to parse capabilities: %s", filename, line, rvalue);
774                 return -EBADMSG;
775         }
776
777         if (c->capabilities)
778                 cap_free(c->capabilities);
779         c->capabilities = cap;
780
781         return 0;
782 }
783
784 static int config_parse_secure_bits(
785                 const char *filename,
786                 unsigned line,
787                 const char *section,
788                 const char *lvalue,
789                 const char *rvalue,
790                 void *data,
791                 void *userdata) {
792
793         ExecContext *c = data;
794         char *w;
795         size_t l;
796         char *state;
797
798         assert(filename);
799         assert(lvalue);
800         assert(rvalue);
801         assert(data);
802
803         FOREACH_WORD(w, l, rvalue, state) {
804                 if (first_word(w, "keep-caps"))
805                         c->secure_bits |= SECURE_KEEP_CAPS;
806                 else if (first_word(w, "keep-caps-locked"))
807                         c->secure_bits |= SECURE_KEEP_CAPS_LOCKED;
808                 else if (first_word(w, "no-setuid-fixup"))
809                         c->secure_bits |= SECURE_NO_SETUID_FIXUP;
810                 else if (first_word(w, "no-setuid-fixup-locked"))
811                         c->secure_bits |= SECURE_NO_SETUID_FIXUP_LOCKED;
812                 else if (first_word(w, "noroot"))
813                         c->secure_bits |= SECURE_NOROOT;
814                 else if (first_word(w, "noroot-locked"))
815                         c->secure_bits |= SECURE_NOROOT_LOCKED;
816                 else {
817                         log_error("[%s:%u] Failed to parse secure bits: %s", filename, line, rvalue);
818                         return -EBADMSG;
819                 }
820         }
821
822         return 0;
823 }
824
825 static int config_parse_bounding_set(
826                 const char *filename,
827                 unsigned line,
828                 const char *section,
829                 const char *lvalue,
830                 const char *rvalue,
831                 void *data,
832                 void *userdata) {
833
834         ExecContext *c = data;
835         char *w;
836         size_t l;
837         char *state;
838
839         assert(filename);
840         assert(lvalue);
841         assert(rvalue);
842         assert(data);
843
844         FOREACH_WORD(w, l, rvalue, state) {
845                 char *t;
846                 int r;
847                 cap_value_t cap;
848
849                 if (!(t = strndup(w, l)))
850                         return -ENOMEM;
851
852                 r = cap_from_name(t, &cap);
853                 free(t);
854
855                 if (r < 0) {
856                         log_error("[%s:%u] Failed to parse capability bounding set: %s", filename, line, rvalue);
857                         return -EBADMSG;
858                 }
859
860                 c->capability_bounding_set_drop |= 1 << cap;
861         }
862
863         return 0;
864 }
865
866 static int config_parse_timer_slack_ns(
867                 const char *filename,
868                 unsigned line,
869                 const char *section,
870                 const char *lvalue,
871                 const char *rvalue,
872                 void *data,
873                 void *userdata) {
874
875         ExecContext *c = data;
876         unsigned long u;
877         int r;
878
879         assert(filename);
880         assert(lvalue);
881         assert(rvalue);
882         assert(data);
883
884         if ((r = safe_atolu(rvalue, &u)) < 0) {
885                 log_error("[%s:%u] Failed to parse time slack value: %s", filename, line, rvalue);
886                 return r;
887         }
888
889         c->timer_slack_ns = u;
890
891         return 0;
892 }
893
894 static int config_parse_limit(
895                 const char *filename,
896                 unsigned line,
897                 const char *section,
898                 const char *lvalue,
899                 const char *rvalue,
900                 void *data,
901                 void *userdata) {
902
903         struct rlimit **rl = data;
904         unsigned long long u;
905         int r;
906
907         assert(filename);
908         assert(lvalue);
909         assert(rvalue);
910         assert(data);
911
912         if ((r = safe_atollu(rvalue, &u)) < 0) {
913                 log_error("[%s:%u] Failed to parse resource value: %s", filename, line, rvalue);
914                 return r;
915         }
916
917         if (!*rl)
918                 if (!(*rl = new(struct rlimit, 1)))
919                         return -ENOMEM;
920
921         (*rl)->rlim_cur = (*rl)->rlim_max = (rlim_t) u;
922         return 0;
923 }
924
925 static int config_parse_cgroup(
926                 const char *filename,
927                 unsigned line,
928                 const char *section,
929                 const char *lvalue,
930                 const char *rvalue,
931                 void *data,
932                 void *userdata) {
933
934         Unit *u = userdata;
935         char *w;
936         size_t l;
937         char *state;
938
939         FOREACH_WORD(w, l, rvalue, state) {
940                 char *t;
941                 int r;
942
943                 if (!(t = strndup(w, l)))
944                         return -ENOMEM;
945
946                 r = unit_add_cgroup_from_text(u, t);
947                 free(t);
948
949                 if (r < 0)
950                         return r;
951         }
952
953         return 0;
954 }
955
956 static int config_parse_sysv_priority(
957                 const char *filename,
958                 unsigned line,
959                 const char *section,
960                 const char *lvalue,
961                 const char *rvalue,
962                 void *data,
963                 void *userdata) {
964
965         int *priority = data;
966         int r, i;
967
968         assert(filename);
969         assert(lvalue);
970         assert(rvalue);
971         assert(data);
972
973         if ((r = safe_atoi(rvalue, &i)) < 0 || i < 0) {
974                 log_error("[%s:%u] Failed to parse SysV start priority: %s", filename, line, rvalue);
975                 return r;
976         }
977
978         *priority = (int) i;
979         return 0;
980 }
981
982 static int config_parse_kill_mode(
983                 const char *filename,
984                 unsigned line,
985                 const char *section,
986                 const char *lvalue,
987                 const char *rvalue,
988                 void *data,
989                 void *userdata) {
990
991         KillMode *m = data, x;
992
993         assert(filename);
994         assert(lvalue);
995         assert(rvalue);
996         assert(data);
997
998         if ((x = kill_mode_from_string(rvalue)) < 0) {
999                 log_error("[%s:%u] Failed to parse kill mode specifier: %s", filename, line, rvalue);
1000                 return -EBADMSG;
1001         }
1002
1003         *m = x;
1004
1005         return 0;
1006 }
1007
1008 #define FOLLOW_MAX 8
1009
1010 static int open_follow(char **filename, FILE **_f, Set *names, char **_id) {
1011         unsigned c = 0;
1012         int fd, r;
1013         FILE *f;
1014         char *id = NULL;
1015
1016         assert(filename);
1017         assert(*filename);
1018         assert(_f);
1019         assert(names);
1020
1021         /* This will update the filename pointer if the loaded file is
1022          * reached by a symlink. The old string will be freed. */
1023
1024         for (;;) {
1025                 char *target, *k, *name;
1026
1027                 if (c++ >= FOLLOW_MAX)
1028                         return -ELOOP;
1029
1030                 path_kill_slashes(*filename);
1031
1032                 /* Add the file name we are currently looking at to
1033                  * the names of this unit */
1034                 name = file_name_from_path(*filename);
1035                 if (!(id = set_get(names, name))) {
1036
1037                         if (!(id = strdup(name)))
1038                                 return -ENOMEM;
1039
1040                         if ((r = set_put(names, id)) < 0) {
1041                                 free(id);
1042                                 return r;
1043                         }
1044                 }
1045
1046                 /* Try to open the file name, but don't if its a symlink */
1047                 if ((fd = open(*filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW)) >= 0)
1048                         break;
1049
1050                 if (errno != ELOOP)
1051                         return -errno;
1052
1053                 /* Hmm, so this is a symlink. Let's read the name, and follow it manually */
1054                 if ((r = readlink_malloc(*filename, &target)) < 0)
1055                         return r;
1056
1057                 k = file_in_same_dir(*filename, target);
1058                 free(target);
1059
1060                 if (!k)
1061                         return -ENOMEM;
1062
1063                 free(*filename);
1064                 *filename = k;
1065         }
1066
1067         if (!(f = fdopen(fd, "r"))) {
1068                 r = -errno;
1069                 assert(close_nointr(fd) == 0);
1070                 return r;
1071         }
1072
1073         *_f = f;
1074         *_id = id;
1075         return 0;
1076 }
1077
1078 static int merge_by_names(Unit **u, Set *names, const char *id) {
1079         char *k;
1080         int r;
1081
1082         assert(u);
1083         assert(*u);
1084         assert(names);
1085
1086         /* Let's try to add in all symlink names we found */
1087         while ((k = set_steal_first(names))) {
1088
1089                 /* First try to merge in the other name into our
1090                  * unit */
1091                 if ((r = unit_merge_by_name(*u, k)) < 0) {
1092                         Unit *other;
1093
1094                         /* Hmm, we couldn't merge the other unit into
1095                          * ours? Then let's try it the other way
1096                          * round */
1097
1098                         other = manager_get_unit((*u)->meta.manager, k);
1099                         free(k);
1100
1101                         if (other)
1102                                 if ((r = unit_merge(other, *u)) >= 0) {
1103                                         *u = other;
1104                                         return merge_by_names(u, names, NULL);
1105                                 }
1106
1107                         return r;
1108                 }
1109
1110                 if (id == k)
1111                         unit_choose_id(*u, id);
1112
1113                 free(k);
1114         }
1115
1116         return 0;
1117 }
1118
1119 static int load_from_path(Unit *u, const char *path, UnitLoadState *new_state) {
1120
1121         static const char* const section_table[_UNIT_TYPE_MAX] = {
1122                 [UNIT_SERVICE]   = "Service",
1123                 [UNIT_TIMER]     = "Timer",
1124                 [UNIT_SOCKET]    = "Socket",
1125                 [UNIT_TARGET]    = "Target",
1126                 [UNIT_DEVICE]    = "Device",
1127                 [UNIT_MOUNT]     = "Mount",
1128                 [UNIT_AUTOMOUNT] = "Automount",
1129                 [UNIT_SNAPSHOT]  = "Snapshot"
1130         };
1131
1132 #define EXEC_CONTEXT_CONFIG_ITEMS(context, section) \
1133                 { "WorkingDirectory",       config_parse_path,            &(context).working_directory,                    section   }, \
1134                 { "RootDirectory",          config_parse_path,            &(context).root_directory,                       section   }, \
1135                 { "User",                   config_parse_string,          &(context).user,                                 section   }, \
1136                 { "Group",                  config_parse_string,          &(context).group,                                section   }, \
1137                 { "SupplementaryGroups",    config_parse_strv,            &(context).supplementary_groups,                 section   }, \
1138                 { "Nice",                   config_parse_nice,            &(context),                                      section   }, \
1139                 { "OOMAdjust",              config_parse_oom_adjust,      &(context),                                      section   }, \
1140                 { "IOSchedulingClass",      config_parse_io_class,        &(context),                                      section   }, \
1141                 { "IOSchedulingPriority",   config_parse_io_priority,     &(context),                                      section   }, \
1142                 { "CPUSchedulingPolicy",    config_parse_cpu_sched_policy,&(context),                                      section   }, \
1143                 { "CPUSchedulingPriority",  config_parse_cpu_sched_prio,  &(context),                                      section   }, \
1144                 { "CPUSchedulingResetOnFork", config_parse_bool,          &(context).cpu_sched_reset_on_fork,              section   }, \
1145                 { "CPUAffinity",            config_parse_cpu_affinity,    &(context),                                      section   }, \
1146                 { "UMask",                  config_parse_mode,            &(context).umask,                                section   }, \
1147                 { "Environment",            config_parse_strv,            &(context).environment,                          section   }, \
1148                 { "Output",                 config_parse_output,          &(context).output,                               section   }, \
1149                 { "Input",                  config_parse_input,           &(context).input,                                section   }, \
1150                 { "SyslogIdentifier",       config_parse_string,          &(context).syslog_identifier,                    section   }, \
1151                 { "SyslogFacility",         config_parse_facility,        &(context).syslog_priority,                      section   }, \
1152                 { "SyslogLevel",            config_parse_level,           &(context).syslog_priority,                      section   }, \
1153                 { "Capabilities",           config_parse_capabilities,    &(context),                                      section   }, \
1154                 { "SecureBits",             config_parse_secure_bits,     &(context),                                      section   }, \
1155                 { "CapabilityBoundingSetDrop", config_parse_bounding_set, &(context),                                      section   }, \
1156                 { "TimerSlackNS",           config_parse_timer_slack_ns,  &(context),                                      section   }, \
1157                 { "LimitCPU",               config_parse_limit,           &(context).rlimit[RLIMIT_CPU],                   section   }, \
1158                 { "LimitFSIZE",             config_parse_limit,           &(context).rlimit[RLIMIT_FSIZE],                 section   }, \
1159                 { "LimitDATA",              config_parse_limit,           &(context).rlimit[RLIMIT_DATA],                  section   }, \
1160                 { "LimitSTACK",             config_parse_limit,           &(context).rlimit[RLIMIT_STACK],                 section   }, \
1161                 { "LimitCORE",              config_parse_limit,           &(context).rlimit[RLIMIT_CORE],                  section   }, \
1162                 { "LimitRSS",               config_parse_limit,           &(context).rlimit[RLIMIT_RSS],                   section   }, \
1163                 { "LimitNOFILE",            config_parse_limit,           &(context).rlimit[RLIMIT_NOFILE],                section   }, \
1164                 { "LimitAS",                config_parse_limit,           &(context).rlimit[RLIMIT_AS],                    section   }, \
1165                 { "LimitNPROC",             config_parse_limit,           &(context).rlimit[RLIMIT_NPROC],                 section   }, \
1166                 { "LimitMEMLOCK",           config_parse_limit,           &(context).rlimit[RLIMIT_MEMLOCK],               section   }, \
1167                 { "LimitLOCKS",             config_parse_limit,           &(context).rlimit[RLIMIT_LOCKS],                 section   }, \
1168                 { "LimitSIGPENDING",        config_parse_limit,           &(context).rlimit[RLIMIT_SIGPENDING],            section   }, \
1169                 { "LimitMSGQUEUE",          config_parse_limit,           &(context).rlimit[RLIMIT_MSGQUEUE],              section   }, \
1170                 { "LimitNICE",              config_parse_limit,           &(context).rlimit[RLIMIT_NICE],                  section   }, \
1171                 { "LimitRTPRIO",            config_parse_limit,           &(context).rlimit[RLIMIT_RTPRIO],                section   }, \
1172                 { "LimitRTTIME",            config_parse_limit,           &(context).rlimit[RLIMIT_RTTIME],                section   }, \
1173                 { "NonBlocking",            config_parse_bool,            &(context).non_blocking,                         section   }, \
1174                 { "ControlGroup",           config_parse_cgroup,          u,                                               section   }, \
1175                 { "NewSession",             config_parse_bool,            &(context).new_session,                          section   }
1176
1177         const ConfigItem items[] = {
1178                 { "Names",                  config_parse_names,           u,                                               "Meta"    },
1179                 { "Description",            config_parse_string,          &u->meta.description,                            "Meta"    },
1180                 { "Requires",               config_parse_deps,            UINT_TO_PTR(UNIT_REQUIRES),                      "Meta"    },
1181                 { "SoftRequires",           config_parse_deps,            UINT_TO_PTR(UNIT_SOFT_REQUIRES),                 "Meta"    },
1182                 { "Wants",                  config_parse_deps,            UINT_TO_PTR(UNIT_WANTS),                         "Meta"    },
1183                 { "Requisite",              config_parse_deps,            UINT_TO_PTR(UNIT_REQUISITE),                     "Meta"    },
1184                 { "SoftRequisite",          config_parse_deps,            UINT_TO_PTR(UNIT_SOFT_REQUISITE),                "Meta"    },
1185                 { "Conflicts",              config_parse_deps,            UINT_TO_PTR(UNIT_CONFLICTS),                     "Meta"    },
1186                 { "Before",                 config_parse_deps,            UINT_TO_PTR(UNIT_BEFORE),                        "Meta"    },
1187                 { "After",                  config_parse_deps,            UINT_TO_PTR(UNIT_AFTER),                         "Meta"    },
1188                 { "RecursiveStop",          config_parse_bool,            &u->meta.recursive_stop,                         "Meta"    },
1189                 { "StopWhenUnneeded",       config_parse_bool,            &u->meta.stop_when_unneeded,                     "Meta"    },
1190
1191                 { "PIDFile",                config_parse_path,            &u->service.pid_file,                            "Service" },
1192                 { "ExecStartPre",           config_parse_exec,            u->service.exec_command+SERVICE_EXEC_START_PRE,  "Service" },
1193                 { "ExecStart",              config_parse_exec,            u->service.exec_command+SERVICE_EXEC_START,      "Service" },
1194                 { "ExecStartPost",          config_parse_exec,            u->service.exec_command+SERVICE_EXEC_START_POST, "Service" },
1195                 { "ExecReload",             config_parse_exec,            u->service.exec_command+SERVICE_EXEC_RELOAD,     "Service" },
1196                 { "ExecStop",               config_parse_exec,            u->service.exec_command+SERVICE_EXEC_STOP,       "Service" },
1197                 { "ExecStopPost",           config_parse_exec,            u->service.exec_command+SERVICE_EXEC_STOP_POST,  "Service" },
1198                 { "RestartSec",             config_parse_usec,            &u->service.restart_usec,                        "Service" },
1199                 { "TimeoutSec",             config_parse_usec,            &u->service.timeout_usec,                        "Service" },
1200                 { "Type",                   config_parse_service_type,    &u->service,                                     "Service" },
1201                 { "Restart",                config_parse_service_restart, &u->service,                                     "Service" },
1202                 { "PermissionsStartOnly",   config_parse_bool,            &u->service.permissions_start_only,              "Service" },
1203                 { "RootDirectoryStartOnly", config_parse_bool,            &u->service.root_directory_start_only,           "Service" },
1204                 { "ValidNoProcess",         config_parse_bool,            &u->service.valid_no_process,                    "Service" },
1205                 { "SysVStartPriority",      config_parse_sysv_priority,   &u->service.sysv_start_priority,                 "Service" },
1206                 { "KillMode",               config_parse_kill_mode,       &u->service.kill_mode,                           "Service" },
1207                 EXEC_CONTEXT_CONFIG_ITEMS(u->service.exec_context, "Service"),
1208
1209                 { "ListenStream",           config_parse_listen,          &u->socket,                                      "Socket"  },
1210                 { "ListenDatagram",         config_parse_listen,          &u->socket,                                      "Socket"  },
1211                 { "ListenSequentialPacket", config_parse_listen,          &u->socket,                                      "Socket"  },
1212                 { "ListenFIFO",             config_parse_listen,          &u->socket,                                      "Socket"  },
1213                 { "BindIPv6Only",           config_parse_socket_bind,     &u->socket,                                      "Socket"  },
1214                 { "Backlog",                config_parse_unsigned,        &u->socket.backlog,                              "Socket"  },
1215                 { "BindToDevice",           config_parse_bindtodevice,    &u->socket,                                      "Socket"  },
1216                 { "ExecStartPre",           config_parse_exec,            u->socket.exec_command+SOCKET_EXEC_START_PRE,    "Socket"  },
1217                 { "ExecStartPost",          config_parse_exec,            u->socket.exec_command+SOCKET_EXEC_START_POST,   "Socket"  },
1218                 { "ExecStopPre",            config_parse_exec,            u->socket.exec_command+SOCKET_EXEC_STOP_PRE,     "Socket"  },
1219                 { "ExecStopPost",           config_parse_exec,            u->socket.exec_command+SOCKET_EXEC_STOP_POST,    "Socket"  },
1220                 { "DirectoryMode",          config_parse_mode,            &u->socket.directory_mode,                       "Socket"  },
1221                 { "SocketMode",             config_parse_mode,            &u->socket.socket_mode,                          "Socket"  },
1222                 { "KillMode",               config_parse_kill_mode,       &u->socket.kill_mode,                            "Socket"  },
1223                 EXEC_CONTEXT_CONFIG_ITEMS(u->socket.exec_context, "Socket"),
1224
1225                 EXEC_CONTEXT_CONFIG_ITEMS(u->automount.exec_context, "Automount"),
1226
1227                 { NULL, NULL, NULL, NULL }
1228         };
1229
1230 #undef EXEC_CONTEXT_CONFIG_ITEMS
1231
1232         const char *sections[3];
1233         char *k;
1234         int r;
1235         Set *symlink_names;
1236         FILE *f = NULL;
1237         char *filename = NULL, *id = NULL;
1238         Unit *merged;
1239
1240         assert(u);
1241         assert(new_state);
1242
1243         sections[0] = "Meta";
1244         sections[1] = section_table[u->meta.type];
1245         sections[2] = NULL;
1246
1247         if (!(symlink_names = set_new(string_hash_func, string_compare_func)))
1248                 return -ENOMEM;
1249
1250         if (path_is_absolute(path)) {
1251
1252                 if (!(filename = strdup(path))) {
1253                         r = -ENOMEM;
1254                         goto finish;
1255                 }
1256
1257                 if ((r = open_follow(&filename, &f, symlink_names, &id)) < 0) {
1258                         free(filename);
1259                         filename = NULL;
1260
1261                         if (r != -ENOENT)
1262                                 goto finish;
1263                 }
1264
1265         } else  {
1266                 char **p;
1267
1268                 STRV_FOREACH(p, u->meta.manager->unit_path) {
1269
1270                         /* Instead of opening the path right away, we manually
1271                          * follow all symlinks and add their name to our unit
1272                          * name set while doing so */
1273                         if (!(filename = path_make_absolute(path, *p))) {
1274                                 r = -ENOMEM;
1275                                 goto finish;
1276                         }
1277
1278                         if ((r = open_follow(&filename, &f, symlink_names, &id)) < 0) {
1279                                 char *sn;
1280
1281                                 free(filename);
1282                                 filename = NULL;
1283
1284                                 if (r != -ENOENT)
1285                                         goto finish;
1286
1287                                 /* Empty the symlink names for the next run */
1288                                 while ((sn = set_steal_first(symlink_names)))
1289                                         free(sn);
1290
1291                                 continue;
1292                         }
1293
1294                         break;
1295                 }
1296         }
1297
1298         if (!filename) {
1299                 r = 0;
1300                 goto finish;
1301         }
1302
1303         merged = u;
1304         if ((r = merge_by_names(&merged, symlink_names, id)) < 0)
1305                 goto finish;
1306
1307         if (merged != u) {
1308                 *new_state = UNIT_MERGED;
1309                 r = 0;
1310                 goto finish;
1311         }
1312
1313         /* Now, parse the file contents */
1314         if ((r = config_parse(filename, f, sections, items, u)) < 0)
1315                 goto finish;
1316
1317         free(u->meta.fragment_path);
1318         u->meta.fragment_path = filename;
1319         filename = NULL;
1320
1321         *new_state = UNIT_LOADED;
1322         r = 0;
1323
1324 finish:
1325         while ((k = set_steal_first(symlink_names)))
1326                 free(k);
1327
1328         set_free(symlink_names);
1329         free(filename);
1330
1331         if (f)
1332                 fclose(f);
1333
1334         return r;
1335 }
1336
1337 int unit_load_fragment(Unit *u, UnitLoadState *new_state) {
1338         int r;
1339
1340         assert(u);
1341         assert(new_state);
1342         assert(*new_state == UNIT_STUB);
1343
1344         if (u->meta.fragment_path) {
1345
1346                 if ((r = load_from_path(u, u->meta.fragment_path, new_state)) < 0)
1347                         return r;
1348
1349         } else {
1350                 Iterator i;
1351                 const char *t;
1352
1353                 /* Try to find the unit under its id */
1354                 if ((t = unit_id(u)))
1355                         if ((r = load_from_path(u, t, new_state)) < 0)
1356                                 return r;
1357
1358                 /* Try to find an alias we can load this with */
1359                 if (*new_state == UNIT_STUB)
1360                         SET_FOREACH(t, u->meta.names, i) {
1361
1362                                 if (unit_id(u) == t)
1363                                         continue;
1364
1365                                 if ((r = load_from_path(u, t, new_state)) < 0)
1366                                         return r;
1367
1368                                 if (*new_state != UNIT_STUB)
1369                                         break;
1370                         }
1371         }
1372
1373         return 0;
1374 }