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