chiark / gitweb /
analyze: Cosmetic exit when the bootup is not yet complete when plotting.
[elogind.git] / src / 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 General Public License as published by
10   the Free Software Foundation; either version 2 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <linux/oom.h>
23 #include <assert.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <sched.h>
29 #include <sys/prctl.h>
30 #include <sys/mount.h>
31 #include <linux/fs.h>
32 #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
2036 #define FOLLOW_MAX 8
2037
2038 static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
2039         unsigned c = 0;
2040         int fd, r;
2041         FILE *f;
2042         char *id = NULL;
2043
2044         assert(filename);
2045         assert(*filename);
2046         assert(_f);
2047         assert(names);
2048
2049         /* This will update the filename pointer if the loaded file is
2050          * reached by a symlink. The old string will be freed. */
2051
2052         for (;;) {
2053                 char *target, *name;
2054
2055                 if (c++ >= FOLLOW_MAX)
2056                         return -ELOOP;
2057
2058                 path_kill_slashes(*filename);
2059
2060                 /* Add the file name we are currently looking at to
2061                  * the names of this unit, but only if it is a valid
2062                  * unit name. */
2063                 name = file_name_from_path(*filename);
2064
2065                 if (unit_name_is_valid(name, true)) {
2066
2067                         id = set_get(names, name);
2068                         if (!id) {
2069                                 id = strdup(name);
2070                                 if (!id)
2071                                         return -ENOMEM;
2072
2073                                 r = set_put(names, id);
2074                                 if (r < 0) {
2075                                         free(id);
2076                                         return r;
2077                                 }
2078                         }
2079                 }
2080
2081                 /* Try to open the file name, but don't if its a symlink */
2082                 if ((fd = open(*filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW)) >= 0)
2083                         break;
2084
2085                 if (errno != ELOOP)
2086                         return -errno;
2087
2088                 /* Hmm, so this is a symlink. Let's read the name, and follow it manually */
2089                 if ((r = readlink_and_make_absolute(*filename, &target)) < 0)
2090                         return r;
2091
2092                 free(*filename);
2093                 *filename = target;
2094         }
2095
2096         if (!(f = fdopen(fd, "re"))) {
2097                 r = -errno;
2098                 close_nointr_nofail(fd);
2099                 return r;
2100         }
2101
2102         *_f = f;
2103         *_final = id;
2104         return 0;
2105 }
2106
2107 static int merge_by_names(Unit **u, Set *names, const char *id) {
2108         char *k;
2109         int r;
2110
2111         assert(u);
2112         assert(*u);
2113         assert(names);
2114
2115         /* Let's try to add in all symlink names we found */
2116         while ((k = set_steal_first(names))) {
2117
2118                 /* First try to merge in the other name into our
2119                  * unit */
2120                 if ((r = unit_merge_by_name(*u, k)) < 0) {
2121                         Unit *other;
2122
2123                         /* Hmm, we couldn't merge the other unit into
2124                          * ours? Then let's try it the other way
2125                          * round */
2126
2127                         other = manager_get_unit((*u)->manager, k);
2128                         free(k);
2129
2130                         if (other)
2131                                 if ((r = unit_merge(other, *u)) >= 0) {
2132                                         *u = other;
2133                                         return merge_by_names(u, names, NULL);
2134                                 }
2135
2136                         return r;
2137                 }
2138
2139                 if (id == k)
2140                         unit_choose_id(*u, id);
2141
2142                 free(k);
2143         }
2144
2145         return 0;
2146 }
2147
2148 static int load_from_path(Unit *u, const char *path) {
2149         int r;
2150         Set *symlink_names;
2151         FILE *f = NULL;
2152         char *filename = NULL, *id = NULL;
2153         Unit *merged;
2154         struct stat st;
2155
2156         assert(u);
2157         assert(path);
2158
2159         symlink_names = set_new(string_hash_func, string_compare_func);
2160         if (!symlink_names)
2161                 return -ENOMEM;
2162
2163         if (path_is_absolute(path)) {
2164
2165                 if (!(filename = strdup(path))) {
2166                         r = -ENOMEM;
2167                         goto finish;
2168                 }
2169
2170                 if ((r = open_follow(&filename, &f, symlink_names, &id)) < 0) {
2171                         free(filename);
2172                         filename = NULL;
2173
2174                         if (r != -ENOENT)
2175                                 goto finish;
2176                 }
2177
2178         } else  {
2179                 char **p;
2180
2181                 STRV_FOREACH(p, u->manager->lookup_paths.unit_path) {
2182
2183                         /* Instead of opening the path right away, we manually
2184                          * follow all symlinks and add their name to our unit
2185                          * name set while doing so */
2186                         if (!(filename = path_make_absolute(path, *p))) {
2187                                 r = -ENOMEM;
2188                                 goto finish;
2189                         }
2190
2191                         if (u->manager->unit_path_cache &&
2192                             !set_get(u->manager->unit_path_cache, filename))
2193                                 r = -ENOENT;
2194                         else
2195                                 r = open_follow(&filename, &f, symlink_names, &id);
2196
2197                         if (r < 0) {
2198                                 char *sn;
2199
2200                                 free(filename);
2201                                 filename = NULL;
2202
2203                                 if (r != -ENOENT)
2204                                         goto finish;
2205
2206                                 /* Empty the symlink names for the next run */
2207                                 while ((sn = set_steal_first(symlink_names)))
2208                                         free(sn);
2209
2210                                 continue;
2211                         }
2212
2213                         break;
2214                 }
2215         }
2216
2217         if (!filename) {
2218                 /* Hmm, no suitable file found? */
2219                 r = 0;
2220                 goto finish;
2221         }
2222
2223         merged = u;
2224         if ((r = merge_by_names(&merged, symlink_names, id)) < 0)
2225                 goto finish;
2226
2227         if (merged != u) {
2228                 u->load_state = UNIT_MERGED;
2229                 r = 0;
2230                 goto finish;
2231         }
2232
2233         zero(st);
2234         if (fstat(fileno(f), &st) < 0) {
2235                 r = -errno;
2236                 goto finish;
2237         }
2238
2239         if (null_or_empty(&st))
2240                 u->load_state = UNIT_MASKED;
2241         else {
2242                 /* Now, parse the file contents */
2243                 r = config_parse(filename, f, UNIT_VTABLE(u)->sections, config_item_perf_lookup, (void*) load_fragment_gperf_lookup, false, u);
2244                 if (r < 0)
2245                         goto finish;
2246
2247                 u->load_state = UNIT_LOADED;
2248         }
2249
2250         free(u->fragment_path);
2251         u->fragment_path = filename;
2252         filename = NULL;
2253
2254         u->fragment_mtime = timespec_load(&st.st_mtim);
2255
2256         r = 0;
2257
2258 finish:
2259         set_free_free(symlink_names);
2260         free(filename);
2261
2262         if (f)
2263                 fclose(f);
2264
2265         return r;
2266 }
2267
2268 int unit_load_fragment(Unit *u) {
2269         int r;
2270         Iterator i;
2271         const char *t;
2272
2273         assert(u);
2274         assert(u->load_state == UNIT_STUB);
2275         assert(u->id);
2276
2277         /* First, try to find the unit under its id. We always look
2278          * for unit files in the default directories, to make it easy
2279          * to override things by placing things in /etc/systemd/system */
2280         if ((r = load_from_path(u, u->id)) < 0)
2281                 return r;
2282
2283         /* Try to find an alias we can load this with */
2284         if (u->load_state == UNIT_STUB)
2285                 SET_FOREACH(t, u->names, i) {
2286
2287                         if (t == u->id)
2288                                 continue;
2289
2290                         if ((r = load_from_path(u, t)) < 0)
2291                                 return r;
2292
2293                         if (u->load_state != UNIT_STUB)
2294                                 break;
2295                 }
2296
2297         /* And now, try looking for it under the suggested (originally linked) path */
2298         if (u->load_state == UNIT_STUB && u->fragment_path) {
2299
2300                 if ((r = load_from_path(u, u->fragment_path)) < 0)
2301                         return r;
2302
2303                 if (u->load_state == UNIT_STUB) {
2304                         /* Hmm, this didn't work? Then let's get rid
2305                          * of the fragment path stored for us, so that
2306                          * we don't point to an invalid location. */
2307                         free(u->fragment_path);
2308                         u->fragment_path = NULL;
2309                 }
2310         }
2311
2312         /* Look for a template */
2313         if (u->load_state == UNIT_STUB && u->instance) {
2314                 char *k;
2315
2316                 if (!(k = unit_name_template(u->id)))
2317                         return -ENOMEM;
2318
2319                 r = load_from_path(u, k);
2320                 free(k);
2321
2322                 if (r < 0)
2323                         return r;
2324
2325                 if (u->load_state == UNIT_STUB)
2326                         SET_FOREACH(t, u->names, i) {
2327
2328                                 if (t == u->id)
2329                                         continue;
2330
2331                                 if (!(k = unit_name_template(t)))
2332                                         return -ENOMEM;
2333
2334                                 r = load_from_path(u, k);
2335                                 free(k);
2336
2337                                 if (r < 0)
2338                                         return r;
2339
2340                                 if (u->load_state != UNIT_STUB)
2341                                         break;
2342                         }
2343         }
2344
2345         return 0;
2346 }
2347
2348 void unit_dump_config_items(FILE *f) {
2349         static const struct {
2350                 const ConfigParserCallback callback;
2351                 const char *rvalue;
2352         } table[] = {
2353                 { config_parse_int,                   "INTEGER" },
2354                 { config_parse_unsigned,              "UNSIGNED" },
2355                 { config_parse_bytes_size,            "SIZE" },
2356                 { config_parse_bool,                  "BOOLEAN" },
2357                 { config_parse_string,                "STRING" },
2358                 { config_parse_path,                  "PATH" },
2359                 { config_parse_unit_path_printf,      "PATH" },
2360                 { config_parse_strv,                  "STRING [...]" },
2361                 { config_parse_exec_nice,             "NICE" },
2362                 { config_parse_exec_oom_score_adjust, "OOMSCOREADJUST" },
2363                 { config_parse_exec_io_class,         "IOCLASS" },
2364                 { config_parse_exec_io_priority,      "IOPRIORITY" },
2365                 { config_parse_exec_cpu_sched_policy, "CPUSCHEDPOLICY" },
2366                 { config_parse_exec_cpu_sched_prio,   "CPUSCHEDPRIO" },
2367                 { config_parse_exec_cpu_affinity,     "CPUAFFINITY" },
2368                 { config_parse_mode,                  "MODE" },
2369                 { config_parse_unit_env_file,         "FILE" },
2370                 { config_parse_output,                "OUTPUT" },
2371                 { config_parse_input,                 "INPUT" },
2372                 { config_parse_facility,              "FACILITY" },
2373                 { config_parse_level,                 "LEVEL" },
2374                 { config_parse_exec_capabilities,     "CAPABILITIES" },
2375                 { config_parse_exec_secure_bits,      "SECUREBITS" },
2376                 { config_parse_exec_bounding_set,     "BOUNDINGSET" },
2377                 { config_parse_exec_timer_slack_nsec, "TIMERSLACK" },
2378                 { config_parse_limit,                 "LIMIT" },
2379                 { config_parse_unit_cgroup,           "CGROUP [...]" },
2380                 { config_parse_unit_deps,             "UNIT [...]" },
2381                 { config_parse_unit_names,            "UNIT [...]" },
2382                 { config_parse_exec,                  "PATH [ARGUMENT [...]]" },
2383                 { config_parse_service_type,          "SERVICETYPE" },
2384                 { config_parse_service_restart,       "SERVICERESTART" },
2385 #ifdef HAVE_SYSV_COMPAT
2386                 { config_parse_sysv_priority,         "SYSVPRIORITY" },
2387 #else
2388                 { config_parse_warn_compat,           "NOTSUPPORTED" },
2389 #endif
2390                 { config_parse_kill_mode,             "KILLMODE" },
2391                 { config_parse_kill_signal,           "SIGNAL" },
2392                 { config_parse_socket_listen,         "SOCKET [...]" },
2393                 { config_parse_socket_bind,           "SOCKETBIND" },
2394                 { config_parse_socket_bindtodevice,   "NETWORKINTERFACE" },
2395                 { config_parse_usec,                  "SECONDS" },
2396                 { config_parse_path_strv,             "PATH [...]" },
2397                 { config_parse_exec_mount_flags,      "MOUNTFLAG [...]" },
2398                 { config_parse_unit_string_printf,    "STRING" },
2399                 { config_parse_timer,                 "TIMER" },
2400                 { config_parse_timer_unit,            "NAME" },
2401                 { config_parse_path_spec,             "PATH" },
2402                 { config_parse_path_unit,             "UNIT" },
2403                 { config_parse_notify_access,         "ACCESS" },
2404                 { config_parse_ip_tos,                "TOS" },
2405                 { config_parse_unit_condition_path,   "CONDITION" },
2406                 { config_parse_unit_condition_string, "CONDITION" },
2407                 { config_parse_unit_condition_null,   "CONDITION" },
2408         };
2409
2410         const char *prev = NULL;
2411         const char *i;
2412
2413         assert(f);
2414
2415         NULSTR_FOREACH(i, load_fragment_gperf_nulstr) {
2416                 const char *rvalue = "OTHER", *lvalue;
2417                 unsigned j;
2418                 size_t prefix_len;
2419                 const char *dot;
2420                 const ConfigPerfItem *p;
2421
2422                 assert_se(p = load_fragment_gperf_lookup(i, strlen(i)));
2423
2424                 dot = strchr(i, '.');
2425                 lvalue = dot ? dot + 1 : i;
2426                 prefix_len = dot-i;
2427
2428                 if (dot)
2429                         if (!prev || strncmp(prev, i, prefix_len+1) != 0) {
2430                                 if (prev)
2431                                         fputc('\n', f);
2432
2433                                 fprintf(f, "[%.*s]\n", (int) prefix_len, i);
2434                         }
2435
2436                 for (j = 0; j < ELEMENTSOF(table); j++)
2437                         if (p->parse == table[j].callback) {
2438                                 rvalue = table[j].rvalue;
2439                                 break;
2440                         }
2441
2442                 fprintf(f, "%s=%s\n", lvalue, rvalue);
2443                 prev = i;
2444         }
2445 }