chiark / gitweb /
unit: add new dependency type RequiresMountsFor=
[elogind.git] / src / core / load-fragment.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <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 #include <sys/stat.h>
33 #include <sys/time.h>
34 #include <sys/resource.h>
35
36 #include "unit.h"
37 #include "strv.h"
38 #include "conf-parser.h"
39 #include "load-fragment.h"
40 #include "log.h"
41 #include "ioprio.h"
42 #include "securebits.h"
43 #include "missing.h"
44 #include "unit-name.h"
45 #include "bus-errors.h"
46 #include "utf8.h"
47
48 #ifndef HAVE_SYSV_COMPAT
49 int config_parse_warn_compat(
50                 const char *filename,
51                 unsigned line,
52                 const char *section,
53                 const char *lvalue,
54                 int ltype,
55                 const char *rvalue,
56                 void *data,
57                 void *userdata) {
58
59         log_debug("[%s:%u] Support for option %s= has been disabled at compile time and is ignored", filename, line, lvalue);
60         return 0;
61 }
62 #endif
63
64 int config_parse_unit_deps(
65                 const char *filename,
66                 unsigned line,
67                 const char *section,
68                 const char *lvalue,
69                 int ltype,
70                 const char *rvalue,
71                 void *data,
72                 void *userdata) {
73
74         UnitDependency d = ltype;
75         Unit *u = userdata;
76         char *w;
77         size_t l;
78         char *state;
79
80         assert(filename);
81         assert(lvalue);
82         assert(rvalue);
83
84         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
85                 char *t, *k;
86                 int r;
87
88                 t = strndup(w, l);
89                 if (!t)
90                         return -ENOMEM;
91
92                 k = unit_name_printf(u, t);
93                 free(t);
94                 if (!k)
95                         return -ENOMEM;
96
97                 r = unit_add_dependency_by_name(u, d, k, NULL, true);
98                 if (r < 0)
99                         log_error("[%s:%u] Failed to add dependency on %s, ignoring: %s", filename, line, k, strerror(-r));
100
101                 free(k);
102         }
103
104         return 0;
105 }
106
107 int config_parse_unit_names(
108                 const char *filename,
109                 unsigned line,
110                 const char *section,
111                 const char *lvalue,
112                 int ltype,
113                 const char *rvalue,
114                 void *data,
115                 void *userdata) {
116
117         Unit *u = userdata;
118         char *w;
119         size_t l;
120         char *state;
121
122         assert(filename);
123         assert(lvalue);
124         assert(rvalue);
125         assert(data);
126
127         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
128                 char *t, *k;
129                 int r;
130
131                 t = strndup(w, l);
132                 if (!t)
133                         return -ENOMEM;
134
135                 k = unit_name_printf(u, t);
136                 free(t);
137                 if (!k)
138                         return -ENOMEM;
139
140                 r = unit_merge_by_name(u, k);
141                 if (r < 0)
142                         log_error("Failed to add name %s, ignoring: %s", k, strerror(-r));
143
144                 free(k);
145         }
146
147         return 0;
148 }
149
150 int config_parse_unit_string_printf(
151                 const char *filename,
152                 unsigned line,
153                 const char *section,
154                 const char *lvalue,
155                 int ltype,
156                 const char *rvalue,
157                 void *data,
158                 void *userdata) {
159
160         Unit *u = userdata;
161         char *k;
162         int r;
163
164         assert(filename);
165         assert(lvalue);
166         assert(rvalue);
167         assert(u);
168
169         k = unit_full_printf(u, rvalue);
170         if (!k)
171                 return -ENOMEM;
172
173         r = config_parse_string(filename, line, section, lvalue, ltype, k, data, userdata);
174         free (k);
175
176         return r;
177 }
178
179 int config_parse_unit_strv_printf(
180                 const char *filename,
181                 unsigned line,
182                 const char *section,
183                 const char *lvalue,
184                 int ltype,
185                 const char *rvalue,
186                 void *data,
187                 void *userdata) {
188
189         Unit *u = userdata;
190         char *k;
191         int r;
192
193         assert(filename);
194         assert(lvalue);
195         assert(rvalue);
196         assert(u);
197
198         k = unit_full_printf(u, rvalue);
199         if (!k)
200                 return -ENOMEM;
201
202         r = config_parse_strv(filename, line, section, lvalue, ltype, k, data, userdata);
203         free(k);
204
205         return r;
206 }
207
208 int config_parse_unit_path_printf(
209                 const char *filename,
210                 unsigned line,
211                 const char *section,
212                 const char *lvalue,
213                 int ltype,
214                 const char *rvalue,
215                 void *data,
216                 void *userdata) {
217
218         Unit *u = userdata;
219         char *k;
220         int r;
221
222         assert(filename);
223         assert(lvalue);
224         assert(rvalue);
225         assert(u);
226
227         k = unit_full_printf(u, rvalue);
228         if (!k)
229                 return -ENOMEM;
230
231         r = config_parse_path(filename, line, section, lvalue, ltype, k, data, userdata);
232         free(k);
233
234         return r;
235 }
236
237 int config_parse_socket_listen(
238                 const char *filename,
239                 unsigned line,
240                 const char *section,
241                 const char *lvalue,
242                 int ltype,
243                 const char *rvalue,
244                 void *data,
245                 void *userdata) {
246
247         SocketPort *p, *tail;
248         Socket *s;
249
250         assert(filename);
251         assert(lvalue);
252         assert(rvalue);
253         assert(data);
254
255         s = SOCKET(data);
256
257         p = new0(SocketPort, 1);
258         if (!p)
259                 return -ENOMEM;
260
261         if (streq(lvalue, "ListenFIFO")) {
262                 p->type = SOCKET_FIFO;
263
264                 if (!(p->path = unit_full_printf(UNIT(s), rvalue))) {
265                         free(p);
266                         return -ENOMEM;
267                 }
268
269                 path_kill_slashes(p->path);
270
271         } else if (streq(lvalue, "ListenSpecial")) {
272                 p->type = SOCKET_SPECIAL;
273
274                 if (!(p->path = unit_full_printf(UNIT(s), rvalue))) {
275                         free(p);
276                         return -ENOMEM;
277                 }
278
279                 path_kill_slashes(p->path);
280
281         } else if (streq(lvalue, "ListenMessageQueue")) {
282
283                 p->type = SOCKET_MQUEUE;
284
285                 if (!(p->path = unit_full_printf(UNIT(s), rvalue))) {
286                         free(p);
287                         return -ENOMEM;
288                 }
289
290                 path_kill_slashes(p->path);
291
292         } else if (streq(lvalue, "ListenNetlink")) {
293                 char  *k;
294                 int r;
295
296                 p->type = SOCKET_SOCKET;
297                 k = unit_full_printf(UNIT(s), rvalue);
298                 r = socket_address_parse_netlink(&p->address, k);
299                 free(k);
300
301                 if (r < 0) {
302                         log_error("[%s:%u] Failed to parse address value, ignoring: %s", filename, line, rvalue);
303                         free(p);
304                         return 0;
305                 }
306
307         } else {
308                 char *k;
309                 int r;
310
311                 p->type = SOCKET_SOCKET;
312                 k = unit_full_printf(UNIT(s), rvalue);
313                 r = socket_address_parse(&p->address, k);
314                 free(k);
315
316                 if (r < 0) {
317                         log_error("[%s:%u] Failed to parse address value, ignoring: %s", filename, line, rvalue);
318                         free(p);
319                         return 0;
320                 }
321
322                 if (streq(lvalue, "ListenStream"))
323                         p->address.type = SOCK_STREAM;
324                 else if (streq(lvalue, "ListenDatagram"))
325                         p->address.type = SOCK_DGRAM;
326                 else {
327                         assert(streq(lvalue, "ListenSequentialPacket"));
328                         p->address.type = SOCK_SEQPACKET;
329                 }
330
331                 if (socket_address_family(&p->address) != AF_LOCAL && p->address.type == SOCK_SEQPACKET) {
332                         log_error("[%s:%u] Address family not supported, ignoring: %s", filename, line, rvalue);
333                         free(p);
334                         return 0;
335                 }
336         }
337
338         p->fd = -1;
339
340         if (s->ports) {
341                 LIST_FIND_TAIL(SocketPort, port, s->ports, tail);
342                 LIST_INSERT_AFTER(SocketPort, port, s->ports, tail, p);
343         } else
344                 LIST_PREPEND(SocketPort, port, s->ports, p);
345
346         return 0;
347 }
348
349 int config_parse_socket_bind(
350                 const char *filename,
351                 unsigned line,
352                 const char *section,
353                 const char *lvalue,
354                 int ltype,
355                 const char *rvalue,
356                 void *data,
357                 void *userdata) {
358
359         Socket *s;
360         SocketAddressBindIPv6Only b;
361
362         assert(filename);
363         assert(lvalue);
364         assert(rvalue);
365         assert(data);
366
367         s = SOCKET(data);
368
369         if ((b = socket_address_bind_ipv6_only_from_string(rvalue)) < 0) {
370                 int r;
371
372                 if ((r = parse_boolean(rvalue)) < 0) {
373                         log_error("[%s:%u] Failed to parse bind IPv6 only value, ignoring: %s", filename, line, rvalue);
374                         return 0;
375                 }
376
377                 s->bind_ipv6_only = r ? SOCKET_ADDRESS_IPV6_ONLY : SOCKET_ADDRESS_BOTH;
378         } else
379                 s->bind_ipv6_only = b;
380
381         return 0;
382 }
383
384 int config_parse_exec_nice(
385                 const char *filename,
386                 unsigned line,
387                 const char *section,
388                 const char *lvalue,
389                 int ltype,
390                 const char *rvalue,
391                 void *data,
392                 void *userdata) {
393
394         ExecContext *c = data;
395         int priority;
396
397         assert(filename);
398         assert(lvalue);
399         assert(rvalue);
400         assert(data);
401
402         if (safe_atoi(rvalue, &priority) < 0) {
403                 log_error("[%s:%u] Failed to parse nice priority, ignoring: %s. ", filename, line, rvalue);
404                 return 0;
405         }
406
407         if (priority < PRIO_MIN || priority >= PRIO_MAX) {
408                 log_error("[%s:%u] Nice priority out of range, ignoring: %s", filename, line, rvalue);
409                 return 0;
410         }
411
412         c->nice = priority;
413         c->nice_set = true;
414
415         return 0;
416 }
417
418 int config_parse_exec_oom_score_adjust(
419                 const char *filename,
420                 unsigned line,
421                 const char *section,
422                 const char *lvalue,
423                 int ltype,
424                 const char *rvalue,
425                 void *data,
426                 void *userdata) {
427
428         ExecContext *c = data;
429         int oa;
430
431         assert(filename);
432         assert(lvalue);
433         assert(rvalue);
434         assert(data);
435
436         if (safe_atoi(rvalue, &oa) < 0) {
437                 log_error("[%s:%u] Failed to parse the OOM score adjust value, ignoring: %s", filename, line, rvalue);
438                 return 0;
439         }
440
441         if (oa < OOM_SCORE_ADJ_MIN || oa > OOM_SCORE_ADJ_MAX) {
442                 log_error("[%s:%u] OOM score adjust value out of range, ignoring: %s", filename, line, rvalue);
443                 return 0;
444         }
445
446         c->oom_score_adjust = oa;
447         c->oom_score_adjust_set = true;
448
449         return 0;
450 }
451
452 int config_parse_exec(
453                 const char *filename,
454                 unsigned line,
455                 const char *section,
456                 const char *lvalue,
457                 int ltype,
458                 const char *rvalue,
459                 void *data,
460                 void *userdata) {
461
462         ExecCommand **e = data, *nce;
463         char *path, **n;
464         unsigned k;
465         int r;
466
467         assert(filename);
468         assert(lvalue);
469         assert(rvalue);
470         assert(e);
471
472         /* We accept an absolute path as first argument, or
473          * alternatively an absolute prefixed with @ to allow
474          * overriding of argv[0]. */
475
476         e += ltype;
477
478         for (;;) {
479                 char *w;
480                 size_t l;
481                 char *state;
482                 bool honour_argv0 = false, ignore = false;
483
484                 path = NULL;
485                 nce = NULL;
486                 n = NULL;
487
488                 rvalue += strspn(rvalue, WHITESPACE);
489
490                 if (rvalue[0] == 0)
491                         break;
492
493                 if (rvalue[0] == '-') {
494                         ignore = true;
495                         rvalue ++;
496                 }
497
498                 if (rvalue[0] == '@') {
499                         honour_argv0 = true;
500                         rvalue ++;
501                 }
502
503                 if (*rvalue != '/') {
504                         log_error("[%s:%u] Invalid executable path in command line, ignoring: %s", filename, line, rvalue);
505                         return 0;
506                 }
507
508                 k = 0;
509                 FOREACH_WORD_QUOTED(w, l, rvalue, state) {
510                         if (strncmp(w, ";", MAX(l, 1U)) == 0)
511                                 break;
512
513                         k++;
514                 }
515
516                 n = new(char*, k + !honour_argv0);
517                 if (!n)
518                         return -ENOMEM;
519
520                 k = 0;
521                 FOREACH_WORD_QUOTED(w, l, rvalue, state) {
522                         if (strncmp(w, ";", MAX(l, 1U)) == 0)
523                                 break;
524
525                         if (honour_argv0 && w == rvalue) {
526                                 assert(!path);
527
528                                 path = strndup(w, l);
529                                 if (!path) {
530                                         r = -ENOMEM;
531                                         goto fail;
532                                 }
533
534                                 if (!utf8_is_valid(path)) {
535                                         log_error("[%s:%u] Path is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
536                                         r = 0;
537                                         goto fail;
538                                 }
539
540                         } else {
541                                 char *c;
542
543                                 c = n[k++] = cunescape_length(w, l);
544                                 if (!c) {
545                                         r = -ENOMEM;
546                                         goto fail;
547                                 }
548
549                                 if (!utf8_is_valid(c)) {
550                                         log_error("[%s:%u] Path is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
551                                         r = 0;
552                                         goto fail;
553                                 }
554                         }
555                 }
556
557                 n[k] = NULL;
558
559                 if (!n[0]) {
560                         log_error("[%s:%u] Invalid command line, ignoring: %s", filename, line, rvalue);
561                         r = 0;
562                         goto fail;
563                 }
564
565                 if (!path) {
566                         path = strdup(n[0]);
567                         if (!path) {
568                                 r = -ENOMEM;
569                                 goto fail;
570                         }
571                 }
572
573                 assert(path_is_absolute(path));
574
575                 nce = new0(ExecCommand, 1);
576                 if (!nce) {
577                         r = -ENOMEM;
578                         goto fail;
579                 }
580
581                 nce->argv = n;
582                 nce->path = path;
583                 nce->ignore = ignore;
584
585                 path_kill_slashes(nce->path);
586
587                 exec_command_append_list(e, nce);
588
589                 rvalue = state;
590         }
591
592         return 0;
593
594 fail:
595         n[k] = NULL;
596         strv_free(n);
597         free(path);
598         free(nce);
599
600         return r;
601 }
602
603 DEFINE_CONFIG_PARSE_ENUM(config_parse_service_type, service_type, ServiceType, "Failed to parse service type");
604 DEFINE_CONFIG_PARSE_ENUM(config_parse_service_restart, service_restart, ServiceRestart, "Failed to parse service restart specifier");
605
606 int config_parse_socket_bindtodevice(
607                 const char *filename,
608                 unsigned line,
609                 const char *section,
610                 const char *lvalue,
611                 int ltype,
612                 const char *rvalue,
613                 void *data,
614                 void *userdata) {
615
616         Socket *s = data;
617         char *n;
618
619         assert(filename);
620         assert(lvalue);
621         assert(rvalue);
622         assert(data);
623
624         if (rvalue[0] && !streq(rvalue, "*")) {
625                 if (!(n = strdup(rvalue)))
626                         return -ENOMEM;
627         } else
628                 n = NULL;
629
630         free(s->bind_to_device);
631         s->bind_to_device = n;
632
633         return 0;
634 }
635
636 DEFINE_CONFIG_PARSE_ENUM(config_parse_output, exec_output, ExecOutput, "Failed to parse output specifier");
637 DEFINE_CONFIG_PARSE_ENUM(config_parse_input, exec_input, ExecInput, "Failed to parse input specifier");
638
639 int config_parse_facility(
640                 const char *filename,
641                 unsigned line,
642                 const char *section,
643                 const char *lvalue,
644                 int ltype,
645                 const char *rvalue,
646                 void *data,
647                 void *userdata) {
648
649
650         int *o = data, x;
651
652         assert(filename);
653         assert(lvalue);
654         assert(rvalue);
655         assert(data);
656
657         if ((x = log_facility_unshifted_from_string(rvalue)) < 0) {
658                 log_error("[%s:%u] Failed to parse log facility, ignoring: %s", filename, line, rvalue);
659                 return 0;
660         }
661
662         *o = (x << 3) | LOG_PRI(*o);
663
664         return 0;
665 }
666
667 int config_parse_level(
668                 const char *filename,
669                 unsigned line,
670                 const char *section,
671                 const char *lvalue,
672                 int ltype,
673                 const char *rvalue,
674                 void *data,
675                 void *userdata) {
676
677
678         int *o = data, x;
679
680         assert(filename);
681         assert(lvalue);
682         assert(rvalue);
683         assert(data);
684
685         if ((x = log_level_from_string(rvalue)) < 0) {
686                 log_error("[%s:%u] Failed to parse log level, ignoring: %s", filename, line, rvalue);
687                 return 0;
688         }
689
690         *o = (*o & LOG_FACMASK) | x;
691         return 0;
692 }
693
694 int config_parse_exec_io_class(
695                 const char *filename,
696                 unsigned line,
697                 const char *section,
698                 const char *lvalue,
699                 int ltype,
700                 const char *rvalue,
701                 void *data,
702                 void *userdata) {
703
704         ExecContext *c = data;
705         int x;
706
707         assert(filename);
708         assert(lvalue);
709         assert(rvalue);
710         assert(data);
711
712         if ((x = ioprio_class_from_string(rvalue)) < 0) {
713                 log_error("[%s:%u] Failed to parse IO scheduling class, ignoring: %s", filename, line, rvalue);
714                 return 0;
715         }
716
717         c->ioprio = IOPRIO_PRIO_VALUE(x, IOPRIO_PRIO_DATA(c->ioprio));
718         c->ioprio_set = true;
719
720         return 0;
721 }
722
723 int config_parse_exec_io_priority(
724                 const char *filename,
725                 unsigned line,
726                 const char *section,
727                 const char *lvalue,
728                 int ltype,
729                 const char *rvalue,
730                 void *data,
731                 void *userdata) {
732
733         ExecContext *c = data;
734         int i;
735
736         assert(filename);
737         assert(lvalue);
738         assert(rvalue);
739         assert(data);
740
741         if (safe_atoi(rvalue, &i) < 0 || i < 0 || i >= IOPRIO_BE_NR) {
742                 log_error("[%s:%u] Failed to parse io priority, ignoring: %s", filename, line, rvalue);
743                 return 0;
744         }
745
746         c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), i);
747         c->ioprio_set = true;
748
749         return 0;
750 }
751
752 int config_parse_exec_cpu_sched_policy(
753                 const char *filename,
754                 unsigned line,
755                 const char *section,
756                 const char *lvalue,
757                 int ltype,
758                 const char *rvalue,
759                 void *data,
760                 void *userdata) {
761
762
763         ExecContext *c = data;
764         int x;
765
766         assert(filename);
767         assert(lvalue);
768         assert(rvalue);
769         assert(data);
770
771         if ((x = sched_policy_from_string(rvalue)) < 0) {
772                 log_error("[%s:%u] Failed to parse CPU scheduling policy, ignoring: %s", filename, line, rvalue);
773                 return 0;
774         }
775
776         c->cpu_sched_policy = x;
777         c->cpu_sched_set = true;
778
779         return 0;
780 }
781
782 int config_parse_exec_cpu_sched_prio(
783                 const char *filename,
784                 unsigned line,
785                 const char *section,
786                 const char *lvalue,
787                 int ltype,
788                 const char *rvalue,
789                 void *data,
790                 void *userdata) {
791
792         ExecContext *c = data;
793         int i;
794
795         assert(filename);
796         assert(lvalue);
797         assert(rvalue);
798         assert(data);
799
800         /* On Linux RR/FIFO have the same range */
801         if (safe_atoi(rvalue, &i) < 0 || i < sched_get_priority_min(SCHED_RR) || i > sched_get_priority_max(SCHED_RR)) {
802                 log_error("[%s:%u] Failed to parse CPU scheduling priority, ignoring: %s", filename, line, rvalue);
803                 return 0;
804         }
805
806         c->cpu_sched_priority = i;
807         c->cpu_sched_set = true;
808
809         return 0;
810 }
811
812 int config_parse_exec_cpu_affinity(
813                 const char *filename,
814                 unsigned line,
815                 const char *section,
816                 const char *lvalue,
817                 int ltype,
818                 const char *rvalue,
819                 void *data,
820                 void *userdata) {
821
822         ExecContext *c = data;
823         char *w;
824         size_t l;
825         char *state;
826
827         assert(filename);
828         assert(lvalue);
829         assert(rvalue);
830         assert(data);
831
832         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
833                 char *t;
834                 int r;
835                 unsigned cpu;
836
837                 if (!(t = strndup(w, l)))
838                         return -ENOMEM;
839
840                 r = safe_atou(t, &cpu);
841                 free(t);
842
843                 if (!(c->cpuset))
844                         if (!(c->cpuset = cpu_set_malloc(&c->cpuset_ncpus)))
845                                 return -ENOMEM;
846
847                 if (r < 0 || cpu >= c->cpuset_ncpus) {
848                         log_error("[%s:%u] Failed to parse CPU affinity, ignoring: %s", filename, line, rvalue);
849                         return 0;
850                 }
851
852                 CPU_SET_S(cpu, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset);
853         }
854
855         return 0;
856 }
857
858 int config_parse_exec_capabilities(
859                 const char *filename,
860                 unsigned line,
861                 const char *section,
862                 const char *lvalue,
863                 int ltype,
864                 const char *rvalue,
865                 void *data,
866                 void *userdata) {
867
868         ExecContext *c = data;
869         cap_t cap;
870
871         assert(filename);
872         assert(lvalue);
873         assert(rvalue);
874         assert(data);
875
876         if (!(cap = cap_from_text(rvalue))) {
877                 if (errno == ENOMEM)
878                         return -ENOMEM;
879
880                 log_error("[%s:%u] Failed to parse capabilities, ignoring: %s", filename, line, rvalue);
881                 return 0;
882         }
883
884         if (c->capabilities)
885                 cap_free(c->capabilities);
886         c->capabilities = cap;
887
888         return 0;
889 }
890
891 int config_parse_exec_secure_bits(
892                 const char *filename,
893                 unsigned line,
894                 const char *section,
895                 const char *lvalue,
896                 int ltype,
897                 const char *rvalue,
898                 void *data,
899                 void *userdata) {
900
901         ExecContext *c = data;
902         char *w;
903         size_t l;
904         char *state;
905
906         assert(filename);
907         assert(lvalue);
908         assert(rvalue);
909         assert(data);
910
911         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
912                 if (first_word(w, "keep-caps"))
913                         c->secure_bits |= SECURE_KEEP_CAPS;
914                 else if (first_word(w, "keep-caps-locked"))
915                         c->secure_bits |= SECURE_KEEP_CAPS_LOCKED;
916                 else if (first_word(w, "no-setuid-fixup"))
917                         c->secure_bits |= SECURE_NO_SETUID_FIXUP;
918                 else if (first_word(w, "no-setuid-fixup-locked"))
919                         c->secure_bits |= SECURE_NO_SETUID_FIXUP_LOCKED;
920                 else if (first_word(w, "noroot"))
921                         c->secure_bits |= SECURE_NOROOT;
922                 else if (first_word(w, "noroot-locked"))
923                         c->secure_bits |= SECURE_NOROOT_LOCKED;
924                 else {
925                         log_error("[%s:%u] Failed to parse secure bits, ignoring: %s", filename, line, rvalue);
926                         return 0;
927                 }
928         }
929
930         return 0;
931 }
932
933 int config_parse_exec_bounding_set(
934                 const char *filename,
935                 unsigned line,
936                 const char *section,
937                 const char *lvalue,
938                 int ltype,
939                 const char *rvalue,
940                 void *data,
941                 void *userdata) {
942
943         ExecContext *c = data;
944         char *w;
945         size_t l;
946         char *state;
947         bool invert = false;
948         uint64_t sum = 0;
949
950         assert(filename);
951         assert(lvalue);
952         assert(rvalue);
953         assert(data);
954
955         if (rvalue[0] == '~') {
956                 invert = true;
957                 rvalue++;
958         }
959
960         /* Note that we store this inverted internally, since the
961          * kernel wants it like this. But we actually expose it
962          * non-inverted everywhere to have a fully normalized
963          * interface. */
964
965         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
966                 char *t;
967                 int r;
968                 cap_value_t cap;
969
970                 if (!(t = strndup(w, l)))
971                         return -ENOMEM;
972
973                 r = cap_from_name(t, &cap);
974                 free(t);
975
976                 if (r < 0) {
977                         log_error("[%s:%u] Failed to parse capability bounding set, ignoring: %s", filename, line, rvalue);
978                         return 0;
979                 }
980
981                 sum |= ((uint64_t) 1ULL) << (uint64_t) cap;
982         }
983
984         if (invert)
985                 c->capability_bounding_set_drop |= sum;
986         else
987                 c->capability_bounding_set_drop |= ~sum;
988
989         return 0;
990 }
991
992 int config_parse_exec_timer_slack_nsec(
993                 const char *filename,
994                 unsigned line,
995                 const char *section,
996                 const char *lvalue,
997                 int ltype,
998                 const char *rvalue,
999                 void *data,
1000                 void *userdata) {
1001
1002         ExecContext *c = data;
1003         unsigned long u;
1004
1005         assert(filename);
1006         assert(lvalue);
1007         assert(rvalue);
1008         assert(data);
1009
1010         if (safe_atolu(rvalue, &u) < 0) {
1011                 log_error("[%s:%u] Failed to parse time slack value, ignoring: %s", filename, line, rvalue);
1012                 return 0;
1013         }
1014
1015         c->timer_slack_nsec = u;
1016
1017         return 0;
1018 }
1019
1020 int config_parse_limit(
1021                 const char *filename,
1022                 unsigned line,
1023                 const char *section,
1024                 const char *lvalue,
1025                 int ltype,
1026                 const char *rvalue,
1027                 void *data,
1028                 void *userdata) {
1029
1030         struct rlimit **rl = data;
1031         unsigned long long u;
1032
1033         assert(filename);
1034         assert(lvalue);
1035         assert(rvalue);
1036         assert(data);
1037
1038         rl += ltype;
1039
1040         if (streq(rvalue, "infinity"))
1041                 u = (unsigned long long) RLIM_INFINITY;
1042         else if (safe_atollu(rvalue, &u) < 0) {
1043                 log_error("[%s:%u] Failed to parse resource value, ignoring: %s", filename, line, rvalue);
1044                 return 0;
1045         }
1046
1047         if (!*rl)
1048                 if (!(*rl = new(struct rlimit, 1)))
1049                         return -ENOMEM;
1050
1051         (*rl)->rlim_cur = (*rl)->rlim_max = (rlim_t) u;
1052         return 0;
1053 }
1054
1055 int config_parse_unit_cgroup(
1056                 const char *filename,
1057                 unsigned line,
1058                 const char *section,
1059                 const char *lvalue,
1060                 int ltype,
1061                 const char *rvalue,
1062                 void *data,
1063                 void *userdata) {
1064
1065         Unit *u = userdata;
1066         char *w;
1067         size_t l;
1068         char *state;
1069
1070         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
1071                 char *t, *k;
1072                 int r;
1073
1074                 t = strndup(w, l);
1075                 if (!t)
1076                         return -ENOMEM;
1077
1078                 k = unit_full_printf(u, t);
1079                 free(t);
1080
1081                 if (!k)
1082                         return -ENOMEM;
1083
1084                 t = cunescape(k);
1085                 free(k);
1086
1087                 if (!t)
1088                         return -ENOMEM;
1089
1090                 r = unit_add_cgroup_from_text(u, t);
1091                 free(t);
1092
1093                 if (r < 0) {
1094                         log_error("[%s:%u] Failed to parse cgroup value, ignoring: %s", filename, line, rvalue);
1095                         return 0;
1096                 }
1097         }
1098
1099         return 0;
1100 }
1101
1102 #ifdef HAVE_SYSV_COMPAT
1103 int config_parse_sysv_priority(
1104                 const char *filename,
1105                 unsigned line,
1106                 const char *section,
1107                 const char *lvalue,
1108                 int ltype,
1109                 const char *rvalue,
1110                 void *data,
1111                 void *userdata) {
1112
1113         int *priority = data;
1114         int i;
1115
1116         assert(filename);
1117         assert(lvalue);
1118         assert(rvalue);
1119         assert(data);
1120
1121         if (safe_atoi(rvalue, &i) < 0 || i < 0) {
1122                 log_error("[%s:%u] Failed to parse SysV start priority, ignoring: %s", filename, line, rvalue);
1123                 return 0;
1124         }
1125
1126         *priority = (int) i;
1127         return 0;
1128 }
1129 #endif
1130
1131 int config_parse_fsck_passno(
1132                 const char *filename,
1133                 unsigned line,
1134                 const char *section,
1135                 const char *lvalue,
1136                 int ltype,
1137                 const char *rvalue,
1138                 void *data,
1139                 void *userdata) {
1140
1141         int *passno = data;
1142         int i;
1143
1144         assert(filename);
1145         assert(lvalue);
1146         assert(rvalue);
1147         assert(data);
1148
1149         if (safe_atoi(rvalue, &i) || i < 0) {
1150                 log_error("[%s:%u] Failed to parse fsck pass number, ignoring: %s", filename, line, rvalue);
1151                 return 0;
1152         }
1153
1154         *passno = (int) i;
1155         return 0;
1156 }
1157
1158 DEFINE_CONFIG_PARSE_ENUM(config_parse_kill_mode, kill_mode, KillMode, "Failed to parse kill mode");
1159
1160 int config_parse_kill_signal(
1161                 const char *filename,
1162                 unsigned line,
1163                 const char *section,
1164                 const char *lvalue,
1165                 int ltype,
1166                 const char *rvalue,
1167                 void *data,
1168                 void *userdata) {
1169
1170         int *sig = data;
1171         int r;
1172
1173         assert(filename);
1174         assert(lvalue);
1175         assert(rvalue);
1176         assert(sig);
1177
1178         if ((r = signal_from_string_try_harder(rvalue)) <= 0) {
1179                 log_error("[%s:%u] Failed to parse kill signal, ignoring: %s", filename, line, rvalue);
1180                 return 0;
1181         }
1182
1183         *sig = r;
1184         return 0;
1185 }
1186
1187 int config_parse_exec_mount_flags(
1188                 const char *filename,
1189                 unsigned line,
1190                 const char *section,
1191                 const char *lvalue,
1192                 int ltype,
1193                 const char *rvalue,
1194                 void *data,
1195                 void *userdata) {
1196
1197         ExecContext *c = data;
1198         char *w;
1199         size_t l;
1200         char *state;
1201         unsigned long flags = 0;
1202
1203         assert(filename);
1204         assert(lvalue);
1205         assert(rvalue);
1206         assert(data);
1207
1208         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
1209                 if (strncmp(w, "shared", MAX(l, 6U)) == 0)
1210                         flags |= MS_SHARED;
1211                 else if (strncmp(w, "slave", MAX(l, 5U)) == 0)
1212                         flags |= MS_SLAVE;
1213                 else if (strncmp(w, "private", MAX(l, 7U)) == 0)
1214                         flags |= MS_PRIVATE;
1215                 else {
1216                         log_error("[%s:%u] Failed to parse mount flags, ignoring: %s", filename, line, rvalue);
1217                         return 0;
1218                 }
1219         }
1220
1221         c->mount_flags = flags;
1222         return 0;
1223 }
1224
1225 int config_parse_timer(
1226                 const char *filename,
1227                 unsigned line,
1228                 const char *section,
1229                 const char *lvalue,
1230                 int ltype,
1231                 const char *rvalue,
1232                 void *data,
1233                 void *userdata) {
1234
1235         Timer *t = data;
1236         usec_t u;
1237         TimerValue *v;
1238         TimerBase b;
1239
1240         assert(filename);
1241         assert(lvalue);
1242         assert(rvalue);
1243         assert(data);
1244
1245         if ((b = timer_base_from_string(lvalue)) < 0) {
1246                 log_error("[%s:%u] Failed to parse timer base, ignoring: %s", filename, line, lvalue);
1247                 return 0;
1248         }
1249
1250         if (parse_usec(rvalue, &u) < 0) {
1251                 log_error("[%s:%u] Failed to parse timer value, ignoring: %s", filename, line, rvalue);
1252                 return 0;
1253         }
1254
1255         if (!(v = new0(TimerValue, 1)))
1256                 return -ENOMEM;
1257
1258         v->base = b;
1259         v->value = u;
1260
1261         LIST_PREPEND(TimerValue, value, t->values, v);
1262
1263         return 0;
1264 }
1265
1266 int config_parse_timer_unit(
1267                 const char *filename,
1268                 unsigned line,
1269                 const char *section,
1270                 const char *lvalue,
1271                 int ltype,
1272                 const char *rvalue,
1273                 void *data,
1274                 void *userdata) {
1275
1276         Timer *t = data;
1277         int r;
1278         DBusError error;
1279         Unit *u;
1280
1281         assert(filename);
1282         assert(lvalue);
1283         assert(rvalue);
1284         assert(data);
1285
1286         dbus_error_init(&error);
1287
1288         if (endswith(rvalue, ".timer")) {
1289                 log_error("[%s:%u] Unit cannot be of type timer, ignoring: %s", filename, line, rvalue);
1290                 return 0;
1291         }
1292
1293         r = manager_load_unit(UNIT(t)->manager, rvalue, NULL, NULL, &u);
1294         if (r < 0) {
1295                 log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r));
1296                 dbus_error_free(&error);
1297                 return 0;
1298         }
1299
1300         unit_ref_set(&t->unit, u);
1301
1302         return 0;
1303 }
1304
1305 int config_parse_path_spec(
1306                 const char *filename,
1307                 unsigned line,
1308                 const char *section,
1309                 const char *lvalue,
1310                 int ltype,
1311                 const char *rvalue,
1312                 void *data,
1313                 void *userdata) {
1314
1315         Path *p = data;
1316         PathSpec *s;
1317         PathType b;
1318
1319         assert(filename);
1320         assert(lvalue);
1321         assert(rvalue);
1322         assert(data);
1323
1324         if ((b = path_type_from_string(lvalue)) < 0) {
1325                 log_error("[%s:%u] Failed to parse path type, ignoring: %s", filename, line, lvalue);
1326                 return 0;
1327         }
1328
1329         if (!path_is_absolute(rvalue)) {
1330                 log_error("[%s:%u] Path is not absolute, ignoring: %s", filename, line, rvalue);
1331                 return 0;
1332         }
1333
1334         if (!(s = new0(PathSpec, 1)))
1335                 return -ENOMEM;
1336
1337         if (!(s->path = strdup(rvalue))) {
1338                 free(s);
1339                 return -ENOMEM;
1340         }
1341
1342         path_kill_slashes(s->path);
1343
1344         s->type = b;
1345         s->inotify_fd = -1;
1346
1347         LIST_PREPEND(PathSpec, spec, p->specs, s);
1348
1349         return 0;
1350 }
1351
1352 int config_parse_path_unit(
1353                 const char *filename,
1354                 unsigned line,
1355                 const char *section,
1356                 const char *lvalue,
1357                 int ltype,
1358                 const char *rvalue,
1359                 void *data,
1360                 void *userdata) {
1361
1362         Path *t = data;
1363         int r;
1364         DBusError error;
1365         Unit *u;
1366
1367         assert(filename);
1368         assert(lvalue);
1369         assert(rvalue);
1370         assert(data);
1371
1372         dbus_error_init(&error);
1373
1374         if (endswith(rvalue, ".path")) {
1375                 log_error("[%s:%u] Unit cannot be of type path, ignoring: %s", filename, line, rvalue);
1376                 return 0;
1377         }
1378
1379         if ((r = manager_load_unit(UNIT(t)->manager, rvalue, NULL, &error, &u)) < 0) {
1380                 log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r));
1381                 dbus_error_free(&error);
1382                 return 0;
1383         }
1384
1385         unit_ref_set(&t->unit, u);
1386
1387         return 0;
1388 }
1389
1390 int config_parse_socket_service(
1391                 const char *filename,
1392                 unsigned line,
1393                 const char *section,
1394                 const char *lvalue,
1395                 int ltype,
1396                 const char *rvalue,
1397                 void *data,
1398                 void *userdata) {
1399
1400         Socket *s = data;
1401         int r;
1402         DBusError error;
1403         Unit *x;
1404
1405         assert(filename);
1406         assert(lvalue);
1407         assert(rvalue);
1408         assert(data);
1409
1410         dbus_error_init(&error);
1411
1412         if (!endswith(rvalue, ".service")) {
1413                 log_error("[%s:%u] Unit must be of type service, ignoring: %s", filename, line, rvalue);
1414                 return 0;
1415         }
1416
1417         r = manager_load_unit(UNIT(s)->manager, rvalue, NULL, &error, &x);
1418         if (r < 0) {
1419                 log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r));
1420                 dbus_error_free(&error);
1421                 return 0;
1422         }
1423
1424         unit_ref_set(&s->service, x);
1425
1426         return 0;
1427 }
1428
1429 int config_parse_service_sockets(
1430                 const char *filename,
1431                 unsigned line,
1432                 const char *section,
1433                 const char *lvalue,
1434                 int ltype,
1435                 const char *rvalue,
1436                 void *data,
1437                 void *userdata) {
1438
1439         Service *s = data;
1440         int r;
1441         char *state, *w;
1442         size_t l;
1443
1444         assert(filename);
1445         assert(lvalue);
1446         assert(rvalue);
1447         assert(data);
1448
1449         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
1450                 char *t, *k;
1451
1452                 t = strndup(w, l);
1453                 if (!t)
1454                         return -ENOMEM;
1455
1456                 k = unit_name_printf(UNIT(s), t);
1457                 free(t);
1458
1459                 if (!k)
1460                         return -ENOMEM;
1461
1462                 if (!endswith(k, ".socket")) {
1463                         log_error("[%s:%u] Unit must be of type socket, ignoring: %s", filename, line, rvalue);
1464                         free(k);
1465                         continue;
1466                 }
1467
1468                 r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_WANTS, UNIT_AFTER, k, NULL, true);
1469                 if (r < 0)
1470                         log_error("[%s:%u] Failed to add dependency on %s, ignoring: %s", filename, line, k, strerror(-r));
1471
1472                 r = unit_add_dependency_by_name(UNIT(s), UNIT_TRIGGERED_BY, k, NULL, true);
1473                 if (r < 0)
1474                         return r;
1475
1476                 free(k);
1477         }
1478
1479         return 0;
1480 }
1481
1482 int config_parse_unit_env_file(
1483                 const char *filename,
1484                 unsigned line,
1485                 const char *section,
1486                 const char *lvalue,
1487                 int ltype,
1488                 const char *rvalue,
1489                 void *data,
1490                 void *userdata) {
1491
1492         char ***env = data, **k;
1493         Unit *u = userdata;
1494         char *s;
1495
1496         assert(filename);
1497         assert(lvalue);
1498         assert(rvalue);
1499         assert(data);
1500
1501         s = unit_full_printf(u, rvalue);
1502         if (!s)
1503                 return -ENOMEM;
1504
1505         if (!path_is_absolute(s[0] == '-' ? s + 1 : s)) {
1506                 log_error("[%s:%u] Path '%s' is not absolute, ignoring.", filename, line, s);
1507                 free(s);
1508                 return 0;
1509         }
1510
1511         k = strv_append(*env, s);
1512         free(s);
1513         if (!k)
1514                 return -ENOMEM;
1515
1516         strv_free(*env);
1517         *env = k;
1518
1519         return 0;
1520 }
1521
1522 int config_parse_ip_tos(
1523                 const char *filename,
1524                 unsigned line,
1525                 const char *section,
1526                 const char *lvalue,
1527                 int ltype,
1528                 const char *rvalue,
1529                 void *data,
1530                 void *userdata) {
1531
1532         int *ip_tos = data, x;
1533
1534         assert(filename);
1535         assert(lvalue);
1536         assert(rvalue);
1537         assert(data);
1538
1539         if ((x = ip_tos_from_string(rvalue)) < 0)
1540                 if (safe_atoi(rvalue, &x) < 0) {
1541                         log_error("[%s:%u] Failed to parse IP TOS value, ignoring: %s", filename, line, rvalue);
1542                         return 0;
1543                 }
1544
1545         *ip_tos = x;
1546         return 0;
1547 }
1548
1549 int config_parse_unit_condition_path(
1550                 const char *filename,
1551                 unsigned line,
1552                 const char *section,
1553                 const char *lvalue,
1554                 int ltype,
1555                 const char *rvalue,
1556                 void *data,
1557                 void *userdata) {
1558
1559         ConditionType cond = ltype;
1560         Unit *u = data;
1561         bool trigger, negate;
1562         Condition *c;
1563
1564         assert(filename);
1565         assert(lvalue);
1566         assert(rvalue);
1567         assert(data);
1568
1569         trigger = rvalue[0] == '|';
1570         if (trigger)
1571                 rvalue++;
1572
1573         negate = rvalue[0] == '!';
1574         if (negate)
1575                 rvalue++;
1576
1577         if (!path_is_absolute(rvalue)) {
1578                 log_error("[%s:%u] Path in condition not absolute, ignoring: %s", filename, line, rvalue);
1579                 return 0;
1580         }
1581
1582         c = condition_new(cond, rvalue, trigger, negate);
1583         if (!c)
1584                 return -ENOMEM;
1585
1586         LIST_PREPEND(Condition, conditions, u->conditions, c);
1587         return 0;
1588 }
1589
1590 int config_parse_unit_condition_string(
1591                 const char *filename,
1592                 unsigned line,
1593                 const char *section,
1594                 const char *lvalue,
1595                 int ltype,
1596                 const char *rvalue,
1597                 void *data,
1598                 void *userdata) {
1599
1600         ConditionType cond = ltype;
1601         Unit *u = data;
1602         bool trigger, negate;
1603         Condition *c;
1604
1605         assert(filename);
1606         assert(lvalue);
1607         assert(rvalue);
1608         assert(data);
1609
1610         if ((trigger = rvalue[0] == '|'))
1611                 rvalue++;
1612
1613         if ((negate = rvalue[0] == '!'))
1614                 rvalue++;
1615
1616         if (!(c = condition_new(cond, rvalue, trigger, negate)))
1617                 return -ENOMEM;
1618
1619         LIST_PREPEND(Condition, conditions, u->conditions, c);
1620         return 0;
1621 }
1622
1623 int config_parse_unit_condition_null(
1624                 const char *filename,
1625                 unsigned line,
1626                 const char *section,
1627                 const char *lvalue,
1628                 int ltype,
1629                 const char *rvalue,
1630                 void *data,
1631                 void *userdata) {
1632
1633         Unit *u = data;
1634         Condition *c;
1635         bool trigger, negate;
1636         int b;
1637
1638         assert(filename);
1639         assert(lvalue);
1640         assert(rvalue);
1641         assert(data);
1642
1643         if ((trigger = rvalue[0] == '|'))
1644                 rvalue++;
1645
1646         if ((negate = rvalue[0] == '!'))
1647                 rvalue++;
1648
1649         if ((b = parse_boolean(rvalue)) < 0) {
1650                 log_error("[%s:%u] Failed to parse boolean value in condition, ignoring: %s", filename, line, rvalue);
1651                 return 0;
1652         }
1653
1654         if (!b)
1655                 negate = !negate;
1656
1657         if (!(c = condition_new(CONDITION_NULL, NULL, trigger, negate)))
1658                 return -ENOMEM;
1659
1660         LIST_PREPEND(Condition, conditions, u->conditions, c);
1661         return 0;
1662 }
1663
1664 DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier");
1665 DEFINE_CONFIG_PARSE_ENUM(config_parse_start_limit_action, start_limit_action, StartLimitAction, "Failed to parse start limit action specifier");
1666
1667 int config_parse_unit_cgroup_attr(
1668                 const char *filename,
1669                 unsigned line,
1670                 const char *section,
1671                 const char *lvalue,
1672                 int ltype,
1673                 const char *rvalue,
1674                 void *data,
1675                 void *userdata) {
1676
1677         Unit *u = data;
1678         char **l;
1679         int r;
1680
1681         assert(filename);
1682         assert(lvalue);
1683         assert(rvalue);
1684         assert(data);
1685
1686         l = strv_split_quoted(rvalue);
1687         if (!l)
1688                 return -ENOMEM;
1689
1690         if (strv_length(l) != 2) {
1691                 log_error("[%s:%u] Failed to parse cgroup attribute value, ignoring: %s", filename, line, rvalue);
1692                 strv_free(l);
1693                 return 0;
1694         }
1695
1696         r = unit_add_cgroup_attribute(u, NULL, l[0], l[1], NULL);
1697         strv_free(l);
1698
1699         if (r < 0) {
1700                 log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
1701                 return 0;
1702         }
1703
1704         return 0;
1705 }
1706
1707 int config_parse_unit_cpu_shares(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
1708         Unit *u = data;
1709         int r;
1710         unsigned long ul;
1711         char *t;
1712
1713         assert(filename);
1714         assert(lvalue);
1715         assert(rvalue);
1716         assert(data);
1717
1718         if (safe_atolu(rvalue, &ul) < 0 || ul < 1) {
1719                 log_error("[%s:%u] Failed to parse CPU shares value, ignoring: %s", filename, line, rvalue);
1720                 return 0;
1721         }
1722
1723         if (asprintf(&t, "%lu", ul) < 0)
1724                 return -ENOMEM;
1725
1726         r = unit_add_cgroup_attribute(u, "cpu", "cpu.shares", t, NULL);
1727         free(t);
1728
1729         if (r < 0) {
1730                 log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
1731                 return 0;
1732         }
1733
1734         return 0;
1735 }
1736
1737 int config_parse_unit_memory_limit(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
1738         Unit *u = data;
1739         int r;
1740         off_t sz;
1741         char *t;
1742
1743         assert(filename);
1744         assert(lvalue);
1745         assert(rvalue);
1746         assert(data);
1747
1748         if (parse_bytes(rvalue, &sz) < 0 || sz <= 0) {
1749                 log_error("[%s:%u] Failed to parse memory limit value, ignoring: %s", filename, line, rvalue);
1750                 return 0;
1751         }
1752
1753         if (asprintf(&t, "%llu", (unsigned long long) sz) < 0)
1754                 return -ENOMEM;
1755
1756         r = unit_add_cgroup_attribute(u,
1757                                       "memory",
1758                                       streq(lvalue, "MemorySoftLimit") ? "memory.soft_limit_in_bytes" : "memory.limit_in_bytes",
1759                                       t, NULL);
1760         free(t);
1761
1762         if (r < 0) {
1763                 log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
1764                 return 0;
1765         }
1766
1767         return 0;
1768 }
1769
1770 static int device_map(const char *controller, const char *name, const char *value, char **ret) {
1771         char **l;
1772
1773         assert(controller);
1774         assert(name);
1775         assert(value);
1776         assert(ret);
1777
1778         l = strv_split_quoted(value);
1779         if (!l)
1780                 return -ENOMEM;
1781
1782         assert(strv_length(l) >= 1);
1783
1784         if (streq(l[0], "*")) {
1785
1786                 if (asprintf(ret, "a *:*%s%s",
1787                              isempty(l[1]) ? "" : " ", strempty(l[1])) < 0) {
1788                         strv_free(l);
1789                         return -ENOMEM;
1790                 }
1791
1792         } else {
1793                 struct stat st;
1794
1795                 if (stat(l[0], &st) < 0) {
1796                         log_warning("Couldn't stat device %s", l[0]);
1797                         strv_free(l);
1798                         return -errno;
1799                 }
1800
1801                 if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) {
1802                         log_warning("%s is not a device.", l[0]);
1803                         strv_free(l);
1804                         return -ENODEV;
1805                 }
1806
1807                 if (asprintf(ret, "%c %u:%u%s%s",
1808                              S_ISCHR(st.st_mode) ? 'c' : 'b',
1809                              major(st.st_rdev), minor(st.st_rdev),
1810                              isempty(l[1]) ? "" : " ", strempty(l[1])) < 0) {
1811
1812                         strv_free(l);
1813                         return -ENOMEM;
1814                 }
1815         }
1816
1817         strv_free(l);
1818         return 0;
1819 }
1820
1821 int config_parse_unit_device_allow(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
1822         Unit *u = data;
1823         char **l;
1824         int r;
1825         unsigned k;
1826
1827         assert(filename);
1828         assert(lvalue);
1829         assert(rvalue);
1830         assert(data);
1831
1832         l = strv_split_quoted(rvalue);
1833         if (!l)
1834                 return -ENOMEM;
1835
1836         k = strv_length(l);
1837         if (k < 1 || k > 2) {
1838                 log_error("[%s:%u] Failed to parse device value, ignoring: %s", filename, line, rvalue);
1839                 strv_free(l);
1840                 return 0;
1841         }
1842
1843         if (!streq(l[0], "*") && !path_startswith(l[0], "/dev")) {
1844                 log_error("[%s:%u] Device node path not absolute, ignoring: %s", filename, line, rvalue);
1845                 strv_free(l);
1846                 return 0;
1847         }
1848
1849         if (!isempty(l[1]) && !in_charset(l[1], "rwm")) {
1850                 log_error("[%s:%u] Device access string invalid, ignoring: %s", filename, line, rvalue);
1851                 strv_free(l);
1852                 return 0;
1853         }
1854         strv_free(l);
1855
1856         r = unit_add_cgroup_attribute(u, "devices",
1857                                       streq(lvalue, "DeviceAllow") ? "devices.allow" : "devices.deny",
1858                                       rvalue, device_map);
1859
1860         if (r < 0) {
1861                 log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
1862                 return 0;
1863         }
1864
1865         return 0;
1866 }
1867
1868 static int blkio_map(const char *controller, const char *name, const char *value, char **ret) {
1869         struct stat st;
1870         char **l;
1871         dev_t d;
1872
1873         assert(controller);
1874         assert(name);
1875         assert(value);
1876         assert(ret);
1877
1878         l = strv_split_quoted(value);
1879         if (!l)
1880                 return -ENOMEM;
1881
1882         assert(strv_length(l) == 2);
1883
1884         if (stat(l[0], &st) < 0) {
1885                 log_warning("Couldn't stat device %s", l[0]);
1886                 strv_free(l);
1887                 return -errno;
1888         }
1889
1890         if (S_ISBLK(st.st_mode))
1891                 d = st.st_rdev;
1892         else if (major(st.st_dev) != 0) {
1893                 /* If this is not a device node then find the block
1894                  * device this file is stored on */
1895                 d = st.st_dev;
1896
1897                 /* If this is a partition, try to get the originating
1898                  * block device */
1899                 block_get_whole_disk(d, &d);
1900         } else {
1901                 log_warning("%s is not a block device and file system block device cannot be determined or is not local.", l[0]);
1902                 strv_free(l);
1903                 return -ENODEV;
1904         }
1905
1906         if (asprintf(ret, "%u:%u %s", major(d), minor(d), l[1]) < 0) {
1907                 strv_free(l);
1908                 return -ENOMEM;
1909         }
1910
1911         strv_free(l);
1912         return 0;
1913 }
1914
1915 int config_parse_unit_blkio_weight(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
1916         Unit *u = data;
1917         int r;
1918         unsigned long ul;
1919         const char *device = NULL, *weight;
1920         unsigned k;
1921         char *t, **l;
1922
1923         assert(filename);
1924         assert(lvalue);
1925         assert(rvalue);
1926         assert(data);
1927
1928         l = strv_split_quoted(rvalue);
1929         if (!l)
1930                 return -ENOMEM;
1931
1932         k = strv_length(l);
1933         if (k < 1 || k > 2) {
1934                 log_error("[%s:%u] Failed to parse weight value, ignoring: %s", filename, line, rvalue);
1935                 strv_free(l);
1936                 return 0;
1937         }
1938
1939         if (k == 1)
1940                 weight = l[0];
1941         else {
1942                 device = l[0];
1943                 weight = l[1];
1944         }
1945
1946         if (device && !path_is_absolute(device)) {
1947                 log_error("[%s:%u] Failed to parse block device node value, ignoring: %s", filename, line, rvalue);
1948                 strv_free(l);
1949                 return 0;
1950         }
1951
1952         if (safe_atolu(weight, &ul) < 0 || ul < 10 || ul > 1000) {
1953                 log_error("[%s:%u] Failed to parse block IO weight value, ignoring: %s", filename, line, rvalue);
1954                 strv_free(l);
1955                 return 0;
1956         }
1957
1958         if (device)
1959                 r = asprintf(&t, "%s %lu", device, ul);
1960         else
1961                 r = asprintf(&t, "%lu", ul);
1962         strv_free(l);
1963
1964         if (r < 0)
1965                 return -ENOMEM;
1966
1967         if (device)
1968                 r = unit_add_cgroup_attribute(u, "blkio", "blkio.weight_device", t, blkio_map);
1969         else
1970                 r = unit_add_cgroup_attribute(u, "blkio", "blkio.weight", t, NULL);
1971         free(t);
1972
1973         if (r < 0) {
1974                 log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
1975                 return 0;
1976         }
1977
1978         return 0;
1979 }
1980
1981 int config_parse_unit_blkio_bandwidth(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
1982         Unit *u = data;
1983         int r;
1984         off_t bytes;
1985         unsigned k;
1986         char *t, **l;
1987
1988         assert(filename);
1989         assert(lvalue);
1990         assert(rvalue);
1991         assert(data);
1992
1993         l = strv_split_quoted(rvalue);
1994         if (!l)
1995                 return -ENOMEM;
1996
1997         k = strv_length(l);
1998         if (k != 2) {
1999                 log_error("[%s:%u] Failed to parse bandwidth value, ignoring: %s", filename, line, rvalue);
2000                 strv_free(l);
2001                 return 0;
2002         }
2003
2004         if (!path_is_absolute(l[0])) {
2005                 log_error("[%s:%u] Failed to parse block device node value, ignoring: %s", filename, line, rvalue);
2006                 strv_free(l);
2007                 return 0;
2008         }
2009
2010         if (parse_bytes(l[1], &bytes) < 0 || bytes <= 0) {
2011                 log_error("[%s:%u] Failed to parse block IO bandwith value, ignoring: %s", filename, line, rvalue);
2012                 strv_free(l);
2013                 return 0;
2014         }
2015
2016         r = asprintf(&t, "%s %llu", l[0], (unsigned long long) bytes);
2017         strv_free(l);
2018
2019         if (r < 0)
2020                 return -ENOMEM;
2021
2022         r = unit_add_cgroup_attribute(u, "blkio",
2023                                       streq(lvalue, "BlockIOReadBandwidth") ? "blkio.read_bps_device" : "blkio.write_bps_device",
2024                                       t, blkio_map);
2025         free(t);
2026
2027         if (r < 0) {
2028                 log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
2029                 return 0;
2030         }
2031
2032         return 0;
2033 }
2034
2035 int config_parse_unit_requires_mounts_for(
2036                 const char *filename,
2037                 unsigned line,
2038                 const char *section,
2039                 const char *lvalue,
2040                 int ltype,
2041                 const char *rvalue,
2042                 void *data,
2043                 void *userdata) {
2044
2045         Unit *u = userdata;
2046         int r;
2047         bool empty_before;
2048
2049         assert(filename);
2050         assert(lvalue);
2051         assert(rvalue);
2052         assert(data);
2053
2054         empty_before = !u->requires_mounts_for;
2055
2056         r = config_parse_path_strv(filename, line, section, lvalue, ltype, rvalue, data, userdata);
2057
2058         /* Make it easy to find units with requires_mounts set */
2059         if (empty_before && u->requires_mounts_for)
2060                 LIST_PREPEND(Unit, has_requires_mounts_for, u->manager->has_requires_mounts_for, u);
2061
2062         return r;
2063 }
2064
2065 #define FOLLOW_MAX 8
2066
2067 static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
2068         unsigned c = 0;
2069         int fd, r;
2070         FILE *f;
2071         char *id = NULL;
2072
2073         assert(filename);
2074         assert(*filename);
2075         assert(_f);
2076         assert(names);
2077
2078         /* This will update the filename pointer if the loaded file is
2079          * reached by a symlink. The old string will be freed. */
2080
2081         for (;;) {
2082                 char *target, *name;
2083
2084                 if (c++ >= FOLLOW_MAX)
2085                         return -ELOOP;
2086
2087                 path_kill_slashes(*filename);
2088
2089                 /* Add the file name we are currently looking at to
2090                  * the names of this unit, but only if it is a valid
2091                  * unit name. */
2092                 name = file_name_from_path(*filename);
2093
2094                 if (unit_name_is_valid(name, true)) {
2095
2096                         id = set_get(names, name);
2097                         if (!id) {
2098                                 id = strdup(name);
2099                                 if (!id)
2100                                         return -ENOMEM;
2101
2102                                 r = set_put(names, id);
2103                                 if (r < 0) {
2104                                         free(id);
2105                                         return r;
2106                                 }
2107                         }
2108                 }
2109
2110                 /* Try to open the file name, but don't if its a symlink */
2111                 if ((fd = open(*filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW)) >= 0)
2112                         break;
2113
2114                 if (errno != ELOOP)
2115                         return -errno;
2116
2117                 /* Hmm, so this is a symlink. Let's read the name, and follow it manually */
2118                 if ((r = readlink_and_make_absolute(*filename, &target)) < 0)
2119                         return r;
2120
2121                 free(*filename);
2122                 *filename = target;
2123         }
2124
2125         if (!(f = fdopen(fd, "re"))) {
2126                 r = -errno;
2127                 close_nointr_nofail(fd);
2128                 return r;
2129         }
2130
2131         *_f = f;
2132         *_final = id;
2133         return 0;
2134 }
2135
2136 static int merge_by_names(Unit **u, Set *names, const char *id) {
2137         char *k;
2138         int r;
2139
2140         assert(u);
2141         assert(*u);
2142         assert(names);
2143
2144         /* Let's try to add in all symlink names we found */
2145         while ((k = set_steal_first(names))) {
2146
2147                 /* First try to merge in the other name into our
2148                  * unit */
2149                 if ((r = unit_merge_by_name(*u, k)) < 0) {
2150                         Unit *other;
2151
2152                         /* Hmm, we couldn't merge the other unit into
2153                          * ours? Then let's try it the other way
2154                          * round */
2155
2156                         other = manager_get_unit((*u)->manager, k);
2157                         free(k);
2158
2159                         if (other)
2160                                 if ((r = unit_merge(other, *u)) >= 0) {
2161                                         *u = other;
2162                                         return merge_by_names(u, names, NULL);
2163                                 }
2164
2165                         return r;
2166                 }
2167
2168                 if (id == k)
2169                         unit_choose_id(*u, id);
2170
2171                 free(k);
2172         }
2173
2174         return 0;
2175 }
2176
2177 static int load_from_path(Unit *u, const char *path) {
2178         int r;
2179         Set *symlink_names;
2180         FILE *f = NULL;
2181         char *filename = NULL, *id = NULL;
2182         Unit *merged;
2183         struct stat st;
2184
2185         assert(u);
2186         assert(path);
2187
2188         symlink_names = set_new(string_hash_func, string_compare_func);
2189         if (!symlink_names)
2190                 return -ENOMEM;
2191
2192         if (path_is_absolute(path)) {
2193
2194                 if (!(filename = strdup(path))) {
2195                         r = -ENOMEM;
2196                         goto finish;
2197                 }
2198
2199                 if ((r = open_follow(&filename, &f, symlink_names, &id)) < 0) {
2200                         free(filename);
2201                         filename = NULL;
2202
2203                         if (r != -ENOENT)
2204                                 goto finish;
2205                 }
2206
2207         } else  {
2208                 char **p;
2209
2210                 STRV_FOREACH(p, u->manager->lookup_paths.unit_path) {
2211
2212                         /* Instead of opening the path right away, we manually
2213                          * follow all symlinks and add their name to our unit
2214                          * name set while doing so */
2215                         if (!(filename = path_make_absolute(path, *p))) {
2216                                 r = -ENOMEM;
2217                                 goto finish;
2218                         }
2219
2220                         if (u->manager->unit_path_cache &&
2221                             !set_get(u->manager->unit_path_cache, filename))
2222                                 r = -ENOENT;
2223                         else
2224                                 r = open_follow(&filename, &f, symlink_names, &id);
2225
2226                         if (r < 0) {
2227                                 char *sn;
2228
2229                                 free(filename);
2230                                 filename = NULL;
2231
2232                                 if (r != -ENOENT)
2233                                         goto finish;
2234
2235                                 /* Empty the symlink names for the next run */
2236                                 while ((sn = set_steal_first(symlink_names)))
2237                                         free(sn);
2238
2239                                 continue;
2240                         }
2241
2242                         break;
2243                 }
2244         }
2245
2246         if (!filename) {
2247                 /* Hmm, no suitable file found? */
2248                 r = 0;
2249                 goto finish;
2250         }
2251
2252         merged = u;
2253         if ((r = merge_by_names(&merged, symlink_names, id)) < 0)
2254                 goto finish;
2255
2256         if (merged != u) {
2257                 u->load_state = UNIT_MERGED;
2258                 r = 0;
2259                 goto finish;
2260         }
2261
2262         zero(st);
2263         if (fstat(fileno(f), &st) < 0) {
2264                 r = -errno;
2265                 goto finish;
2266         }
2267
2268         if (null_or_empty(&st))
2269                 u->load_state = UNIT_MASKED;
2270         else {
2271                 /* Now, parse the file contents */
2272                 r = config_parse(filename, f, UNIT_VTABLE(u)->sections, config_item_perf_lookup, (void*) load_fragment_gperf_lookup, false, u);
2273                 if (r < 0)
2274                         goto finish;
2275
2276                 u->load_state = UNIT_LOADED;
2277         }
2278
2279         free(u->fragment_path);
2280         u->fragment_path = filename;
2281         filename = NULL;
2282
2283         u->fragment_mtime = timespec_load(&st.st_mtim);
2284
2285         r = 0;
2286
2287 finish:
2288         set_free_free(symlink_names);
2289         free(filename);
2290
2291         if (f)
2292                 fclose(f);
2293
2294         return r;
2295 }
2296
2297 int unit_load_fragment(Unit *u) {
2298         int r;
2299         Iterator i;
2300         const char *t;
2301
2302         assert(u);
2303         assert(u->load_state == UNIT_STUB);
2304         assert(u->id);
2305
2306         /* First, try to find the unit under its id. We always look
2307          * for unit files in the default directories, to make it easy
2308          * to override things by placing things in /etc/systemd/system */
2309         if ((r = load_from_path(u, u->id)) < 0)
2310                 return r;
2311
2312         /* Try to find an alias we can load this with */
2313         if (u->load_state == UNIT_STUB)
2314                 SET_FOREACH(t, u->names, i) {
2315
2316                         if (t == u->id)
2317                                 continue;
2318
2319                         if ((r = load_from_path(u, t)) < 0)
2320                                 return r;
2321
2322                         if (u->load_state != UNIT_STUB)
2323                                 break;
2324                 }
2325
2326         /* And now, try looking for it under the suggested (originally linked) path */
2327         if (u->load_state == UNIT_STUB && u->fragment_path) {
2328
2329                 if ((r = load_from_path(u, u->fragment_path)) < 0)
2330                         return r;
2331
2332                 if (u->load_state == UNIT_STUB) {
2333                         /* Hmm, this didn't work? Then let's get rid
2334                          * of the fragment path stored for us, so that
2335                          * we don't point to an invalid location. */
2336                         free(u->fragment_path);
2337                         u->fragment_path = NULL;
2338                 }
2339         }
2340
2341         /* Look for a template */
2342         if (u->load_state == UNIT_STUB && u->instance) {
2343                 char *k;
2344
2345                 if (!(k = unit_name_template(u->id)))
2346                         return -ENOMEM;
2347
2348                 r = load_from_path(u, k);
2349                 free(k);
2350
2351                 if (r < 0)
2352                         return r;
2353
2354                 if (u->load_state == UNIT_STUB)
2355                         SET_FOREACH(t, u->names, i) {
2356
2357                                 if (t == u->id)
2358                                         continue;
2359
2360                                 if (!(k = unit_name_template(t)))
2361                                         return -ENOMEM;
2362
2363                                 r = load_from_path(u, k);
2364                                 free(k);
2365
2366                                 if (r < 0)
2367                                         return r;
2368
2369                                 if (u->load_state != UNIT_STUB)
2370                                         break;
2371                         }
2372         }
2373
2374         return 0;
2375 }
2376
2377 void unit_dump_config_items(FILE *f) {
2378         static const struct {
2379                 const ConfigParserCallback callback;
2380                 const char *rvalue;
2381         } table[] = {
2382                 { config_parse_int,                   "INTEGER" },
2383                 { config_parse_unsigned,              "UNSIGNED" },
2384                 { config_parse_bytes_size,            "SIZE" },
2385                 { config_parse_bool,                  "BOOLEAN" },
2386                 { config_parse_string,                "STRING" },
2387                 { config_parse_path,                  "PATH" },
2388                 { config_parse_unit_path_printf,      "PATH" },
2389                 { config_parse_strv,                  "STRING [...]" },
2390                 { config_parse_exec_nice,             "NICE" },
2391                 { config_parse_exec_oom_score_adjust, "OOMSCOREADJUST" },
2392                 { config_parse_exec_io_class,         "IOCLASS" },
2393                 { config_parse_exec_io_priority,      "IOPRIORITY" },
2394                 { config_parse_exec_cpu_sched_policy, "CPUSCHEDPOLICY" },
2395                 { config_parse_exec_cpu_sched_prio,   "CPUSCHEDPRIO" },
2396                 { config_parse_exec_cpu_affinity,     "CPUAFFINITY" },
2397                 { config_parse_mode,                  "MODE" },
2398                 { config_parse_unit_env_file,         "FILE" },
2399                 { config_parse_output,                "OUTPUT" },
2400                 { config_parse_input,                 "INPUT" },
2401                 { config_parse_facility,              "FACILITY" },
2402                 { config_parse_level,                 "LEVEL" },
2403                 { config_parse_exec_capabilities,     "CAPABILITIES" },
2404                 { config_parse_exec_secure_bits,      "SECUREBITS" },
2405                 { config_parse_exec_bounding_set,     "BOUNDINGSET" },
2406                 { config_parse_exec_timer_slack_nsec, "TIMERSLACK" },
2407                 { config_parse_limit,                 "LIMIT" },
2408                 { config_parse_unit_cgroup,           "CGROUP [...]" },
2409                 { config_parse_unit_deps,             "UNIT [...]" },
2410                 { config_parse_unit_names,            "UNIT [...]" },
2411                 { config_parse_exec,                  "PATH [ARGUMENT [...]]" },
2412                 { config_parse_service_type,          "SERVICETYPE" },
2413                 { config_parse_service_restart,       "SERVICERESTART" },
2414 #ifdef HAVE_SYSV_COMPAT
2415                 { config_parse_sysv_priority,         "SYSVPRIORITY" },
2416 #else
2417                 { config_parse_warn_compat,           "NOTSUPPORTED" },
2418 #endif
2419                 { config_parse_kill_mode,             "KILLMODE" },
2420                 { config_parse_kill_signal,           "SIGNAL" },
2421                 { config_parse_socket_listen,         "SOCKET [...]" },
2422                 { config_parse_socket_bind,           "SOCKETBIND" },
2423                 { config_parse_socket_bindtodevice,   "NETWORKINTERFACE" },
2424                 { config_parse_usec,                  "SECONDS" },
2425                 { config_parse_path_strv,             "PATH [...]" },
2426                 { config_parse_unit_requires_mounts_for, "PATH [...]" },
2427                 { config_parse_exec_mount_flags,      "MOUNTFLAG [...]" },
2428                 { config_parse_unit_string_printf,    "STRING" },
2429                 { config_parse_timer,                 "TIMER" },
2430                 { config_parse_timer_unit,            "NAME" },
2431                 { config_parse_path_spec,             "PATH" },
2432                 { config_parse_path_unit,             "UNIT" },
2433                 { config_parse_notify_access,         "ACCESS" },
2434                 { config_parse_ip_tos,                "TOS" },
2435                 { config_parse_unit_condition_path,   "CONDITION" },
2436                 { config_parse_unit_condition_string, "CONDITION" },
2437                 { config_parse_unit_condition_null,   "CONDITION" },
2438         };
2439
2440         const char *prev = NULL;
2441         const char *i;
2442
2443         assert(f);
2444
2445         NULSTR_FOREACH(i, load_fragment_gperf_nulstr) {
2446                 const char *rvalue = "OTHER", *lvalue;
2447                 unsigned j;
2448                 size_t prefix_len;
2449                 const char *dot;
2450                 const ConfigPerfItem *p;
2451
2452                 assert_se(p = load_fragment_gperf_lookup(i, strlen(i)));
2453
2454                 dot = strchr(i, '.');
2455                 lvalue = dot ? dot + 1 : i;
2456                 prefix_len = dot-i;
2457
2458                 if (dot)
2459                         if (!prev || strncmp(prev, i, prefix_len+1) != 0) {
2460                                 if (prev)
2461                                         fputc('\n', f);
2462
2463                                 fprintf(f, "[%.*s]\n", (int) prefix_len, i);
2464                         }
2465
2466                 for (j = 0; j < ELEMENTSOF(table); j++)
2467                         if (p->parse == table[j].callback) {
2468                                 rvalue = table[j].rvalue;
2469                                 break;
2470                         }
2471
2472                 fprintf(f, "%s=%s\n", lvalue, rvalue);
2473                 prev = i;
2474         }
2475 }