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