chiark / gitweb /
22da6c1197e70e95d42c4ae7db61990be2f01a83
[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_service_timeout(
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         Service *s = userdata;
1412         int r;
1413
1414         assert(filename);
1415         assert(lvalue);
1416         assert(rvalue);
1417         assert(s);
1418
1419         r = config_parse_usec(filename, line, section, lvalue, ltype, rvalue, data, userdata);
1420
1421         if (!r)
1422                 s->timeout_defined = true;
1423
1424         return r;
1425 }
1426
1427 int config_parse_unit_env_file(
1428                 const char *filename,
1429                 unsigned line,
1430                 const char *section,
1431                 const char *lvalue,
1432                 int ltype,
1433                 const char *rvalue,
1434                 void *data,
1435                 void *userdata) {
1436
1437         char ***env = data, **k;
1438         Unit *u = userdata;
1439         char *s;
1440
1441         assert(filename);
1442         assert(lvalue);
1443         assert(rvalue);
1444         assert(data);
1445
1446         s = unit_full_printf(u, rvalue);
1447         if (!s)
1448                 return -ENOMEM;
1449
1450         if (!path_is_absolute(s[0] == '-' ? s + 1 : s)) {
1451                 log_error("[%s:%u] Path '%s' is not absolute, ignoring.", filename, line, s);
1452                 free(s);
1453                 return 0;
1454         }
1455
1456         k = strv_append(*env, s);
1457         free(s);
1458         if (!k)
1459                 return -ENOMEM;
1460
1461         strv_free(*env);
1462         *env = k;
1463
1464         return 0;
1465 }
1466
1467 int config_parse_ip_tos(
1468                 const char *filename,
1469                 unsigned line,
1470                 const char *section,
1471                 const char *lvalue,
1472                 int ltype,
1473                 const char *rvalue,
1474                 void *data,
1475                 void *userdata) {
1476
1477         int *ip_tos = data, x;
1478
1479         assert(filename);
1480         assert(lvalue);
1481         assert(rvalue);
1482         assert(data);
1483
1484         if ((x = ip_tos_from_string(rvalue)) < 0)
1485                 if (safe_atoi(rvalue, &x) < 0) {
1486                         log_error("[%s:%u] Failed to parse IP TOS value, ignoring: %s", filename, line, rvalue);
1487                         return 0;
1488                 }
1489
1490         *ip_tos = x;
1491         return 0;
1492 }
1493
1494 int config_parse_unit_condition_path(
1495                 const char *filename,
1496                 unsigned line,
1497                 const char *section,
1498                 const char *lvalue,
1499                 int ltype,
1500                 const char *rvalue,
1501                 void *data,
1502                 void *userdata) {
1503
1504         ConditionType cond = ltype;
1505         Unit *u = data;
1506         bool trigger, negate;
1507         Condition *c;
1508
1509         assert(filename);
1510         assert(lvalue);
1511         assert(rvalue);
1512         assert(data);
1513
1514         trigger = rvalue[0] == '|';
1515         if (trigger)
1516                 rvalue++;
1517
1518         negate = rvalue[0] == '!';
1519         if (negate)
1520                 rvalue++;
1521
1522         if (!path_is_absolute(rvalue)) {
1523                 log_error("[%s:%u] Path in condition not absolute, ignoring: %s", filename, line, rvalue);
1524                 return 0;
1525         }
1526
1527         c = condition_new(cond, rvalue, trigger, negate);
1528         if (!c)
1529                 return -ENOMEM;
1530
1531         LIST_PREPEND(Condition, conditions, u->conditions, c);
1532         return 0;
1533 }
1534
1535 int config_parse_unit_condition_string(
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         if ((trigger = rvalue[0] == '|'))
1556                 rvalue++;
1557
1558         if ((negate = rvalue[0] == '!'))
1559                 rvalue++;
1560
1561         if (!(c = condition_new(cond, rvalue, trigger, negate)))
1562                 return -ENOMEM;
1563
1564         LIST_PREPEND(Condition, conditions, u->conditions, c);
1565         return 0;
1566 }
1567
1568 int config_parse_unit_condition_null(
1569                 const char *filename,
1570                 unsigned line,
1571                 const char *section,
1572                 const char *lvalue,
1573                 int ltype,
1574                 const char *rvalue,
1575                 void *data,
1576                 void *userdata) {
1577
1578         Unit *u = data;
1579         Condition *c;
1580         bool trigger, negate;
1581         int b;
1582
1583         assert(filename);
1584         assert(lvalue);
1585         assert(rvalue);
1586         assert(data);
1587
1588         if ((trigger = rvalue[0] == '|'))
1589                 rvalue++;
1590
1591         if ((negate = rvalue[0] == '!'))
1592                 rvalue++;
1593
1594         if ((b = parse_boolean(rvalue)) < 0) {
1595                 log_error("[%s:%u] Failed to parse boolean value in condition, ignoring: %s", filename, line, rvalue);
1596                 return 0;
1597         }
1598
1599         if (!b)
1600                 negate = !negate;
1601
1602         if (!(c = condition_new(CONDITION_NULL, NULL, trigger, negate)))
1603                 return -ENOMEM;
1604
1605         LIST_PREPEND(Condition, conditions, u->conditions, c);
1606         return 0;
1607 }
1608
1609 DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier");
1610 DEFINE_CONFIG_PARSE_ENUM(config_parse_start_limit_action, start_limit_action, StartLimitAction, "Failed to parse start limit action specifier");
1611
1612 int config_parse_unit_cgroup_attr(
1613                 const char *filename,
1614                 unsigned line,
1615                 const char *section,
1616                 const char *lvalue,
1617                 int ltype,
1618                 const char *rvalue,
1619                 void *data,
1620                 void *userdata) {
1621
1622         Unit *u = data;
1623         char **l;
1624         int r;
1625
1626         assert(filename);
1627         assert(lvalue);
1628         assert(rvalue);
1629         assert(data);
1630
1631         l = strv_split_quoted(rvalue);
1632         if (!l)
1633                 return -ENOMEM;
1634
1635         if (strv_length(l) != 2) {
1636                 log_error("[%s:%u] Failed to parse cgroup attribute value, ignoring: %s", filename, line, rvalue);
1637                 strv_free(l);
1638                 return 0;
1639         }
1640
1641         r = unit_add_cgroup_attribute(u, NULL, l[0], l[1], NULL);
1642         strv_free(l);
1643
1644         if (r < 0) {
1645                 log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
1646                 return 0;
1647         }
1648
1649         return 0;
1650 }
1651
1652 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) {
1653         Unit *u = data;
1654         int r;
1655         unsigned long ul;
1656         char *t;
1657
1658         assert(filename);
1659         assert(lvalue);
1660         assert(rvalue);
1661         assert(data);
1662
1663         if (safe_atolu(rvalue, &ul) < 0 || ul < 1) {
1664                 log_error("[%s:%u] Failed to parse CPU shares value, ignoring: %s", filename, line, rvalue);
1665                 return 0;
1666         }
1667
1668         if (asprintf(&t, "%lu", ul) < 0)
1669                 return -ENOMEM;
1670
1671         r = unit_add_cgroup_attribute(u, "cpu", "cpu.shares", t, NULL);
1672         free(t);
1673
1674         if (r < 0) {
1675                 log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
1676                 return 0;
1677         }
1678
1679         return 0;
1680 }
1681
1682 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) {
1683         Unit *u = data;
1684         int r;
1685         off_t sz;
1686         char *t;
1687
1688         assert(filename);
1689         assert(lvalue);
1690         assert(rvalue);
1691         assert(data);
1692
1693         if (parse_bytes(rvalue, &sz) < 0 || sz <= 0) {
1694                 log_error("[%s:%u] Failed to parse memory limit value, ignoring: %s", filename, line, rvalue);
1695                 return 0;
1696         }
1697
1698         if (asprintf(&t, "%llu", (unsigned long long) sz) < 0)
1699                 return -ENOMEM;
1700
1701         r = unit_add_cgroup_attribute(u,
1702                                       "memory",
1703                                       streq(lvalue, "MemorySoftLimit") ? "memory.soft_limit_in_bytes" : "memory.limit_in_bytes",
1704                                       t, NULL);
1705         free(t);
1706
1707         if (r < 0) {
1708                 log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
1709                 return 0;
1710         }
1711
1712         return 0;
1713 }
1714
1715 static int device_map(const char *controller, const char *name, const char *value, char **ret) {
1716         char **l;
1717
1718         assert(controller);
1719         assert(name);
1720         assert(value);
1721         assert(ret);
1722
1723         l = strv_split_quoted(value);
1724         if (!l)
1725                 return -ENOMEM;
1726
1727         assert(strv_length(l) >= 1);
1728
1729         if (streq(l[0], "*")) {
1730
1731                 if (asprintf(ret, "a *:*%s%s",
1732                              isempty(l[1]) ? "" : " ", strempty(l[1])) < 0) {
1733                         strv_free(l);
1734                         return -ENOMEM;
1735                 }
1736
1737         } else {
1738                 struct stat st;
1739
1740                 if (stat(l[0], &st) < 0) {
1741                         log_warning("Couldn't stat device %s", l[0]);
1742                         strv_free(l);
1743                         return -errno;
1744                 }
1745
1746                 if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) {
1747                         log_warning("%s is not a device.", l[0]);
1748                         strv_free(l);
1749                         return -ENODEV;
1750                 }
1751
1752                 if (asprintf(ret, "%c %u:%u%s%s",
1753                              S_ISCHR(st.st_mode) ? 'c' : 'b',
1754                              major(st.st_rdev), minor(st.st_rdev),
1755                              isempty(l[1]) ? "" : " ", strempty(l[1])) < 0) {
1756
1757                         strv_free(l);
1758                         return -ENOMEM;
1759                 }
1760         }
1761
1762         strv_free(l);
1763         return 0;
1764 }
1765
1766 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) {
1767         Unit *u = data;
1768         char **l;
1769         int r;
1770         unsigned k;
1771
1772         assert(filename);
1773         assert(lvalue);
1774         assert(rvalue);
1775         assert(data);
1776
1777         l = strv_split_quoted(rvalue);
1778         if (!l)
1779                 return -ENOMEM;
1780
1781         k = strv_length(l);
1782         if (k < 1 || k > 2) {
1783                 log_error("[%s:%u] Failed to parse device value, ignoring: %s", filename, line, rvalue);
1784                 strv_free(l);
1785                 return 0;
1786         }
1787
1788         if (!streq(l[0], "*") && !path_startswith(l[0], "/dev")) {
1789                 log_error("[%s:%u] Device node path not absolute, ignoring: %s", filename, line, rvalue);
1790                 strv_free(l);
1791                 return 0;
1792         }
1793
1794         if (!isempty(l[1]) && !in_charset(l[1], "rwm")) {
1795                 log_error("[%s:%u] Device access string invalid, ignoring: %s", filename, line, rvalue);
1796                 strv_free(l);
1797                 return 0;
1798         }
1799         strv_free(l);
1800
1801         r = unit_add_cgroup_attribute(u, "devices",
1802                                       streq(lvalue, "DeviceAllow") ? "devices.allow" : "devices.deny",
1803                                       rvalue, device_map);
1804
1805         if (r < 0) {
1806                 log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
1807                 return 0;
1808         }
1809
1810         return 0;
1811 }
1812
1813 static int blkio_map(const char *controller, const char *name, const char *value, char **ret) {
1814         struct stat st;
1815         char **l;
1816         dev_t d;
1817
1818         assert(controller);
1819         assert(name);
1820         assert(value);
1821         assert(ret);
1822
1823         l = strv_split_quoted(value);
1824         if (!l)
1825                 return -ENOMEM;
1826
1827         assert(strv_length(l) == 2);
1828
1829         if (stat(l[0], &st) < 0) {
1830                 log_warning("Couldn't stat device %s", l[0]);
1831                 strv_free(l);
1832                 return -errno;
1833         }
1834
1835         if (S_ISBLK(st.st_mode))
1836                 d = st.st_rdev;
1837         else if (major(st.st_dev) != 0) {
1838                 /* If this is not a device node then find the block
1839                  * device this file is stored on */
1840                 d = st.st_dev;
1841
1842                 /* If this is a partition, try to get the originating
1843                  * block device */
1844                 block_get_whole_disk(d, &d);
1845         } else {
1846                 log_warning("%s is not a block device and file system block device cannot be determined or is not local.", l[0]);
1847                 strv_free(l);
1848                 return -ENODEV;
1849         }
1850
1851         if (asprintf(ret, "%u:%u %s", major(d), minor(d), l[1]) < 0) {
1852                 strv_free(l);
1853                 return -ENOMEM;
1854         }
1855
1856         strv_free(l);
1857         return 0;
1858 }
1859
1860 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) {
1861         Unit *u = data;
1862         int r;
1863         unsigned long ul;
1864         const char *device = NULL, *weight;
1865         unsigned k;
1866         char *t, **l;
1867
1868         assert(filename);
1869         assert(lvalue);
1870         assert(rvalue);
1871         assert(data);
1872
1873         l = strv_split_quoted(rvalue);
1874         if (!l)
1875                 return -ENOMEM;
1876
1877         k = strv_length(l);
1878         if (k < 1 || k > 2) {
1879                 log_error("[%s:%u] Failed to parse weight value, ignoring: %s", filename, line, rvalue);
1880                 strv_free(l);
1881                 return 0;
1882         }
1883
1884         if (k == 1)
1885                 weight = l[0];
1886         else {
1887                 device = l[0];
1888                 weight = l[1];
1889         }
1890
1891         if (device && !path_is_absolute(device)) {
1892                 log_error("[%s:%u] Failed to parse block device node value, ignoring: %s", filename, line, rvalue);
1893                 strv_free(l);
1894                 return 0;
1895         }
1896
1897         if (safe_atolu(weight, &ul) < 0 || ul < 10 || ul > 1000) {
1898                 log_error("[%s:%u] Failed to parse block IO weight value, ignoring: %s", filename, line, rvalue);
1899                 strv_free(l);
1900                 return 0;
1901         }
1902
1903         if (device)
1904                 r = asprintf(&t, "%s %lu", device, ul);
1905         else
1906                 r = asprintf(&t, "%lu", ul);
1907         strv_free(l);
1908
1909         if (r < 0)
1910                 return -ENOMEM;
1911
1912         if (device)
1913                 r = unit_add_cgroup_attribute(u, "blkio", "blkio.weight_device", t, blkio_map);
1914         else
1915                 r = unit_add_cgroup_attribute(u, "blkio", "blkio.weight", t, NULL);
1916         free(t);
1917
1918         if (r < 0) {
1919                 log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
1920                 return 0;
1921         }
1922
1923         return 0;
1924 }
1925
1926 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) {
1927         Unit *u = data;
1928         int r;
1929         off_t bytes;
1930         unsigned k;
1931         char *t, **l;
1932
1933         assert(filename);
1934         assert(lvalue);
1935         assert(rvalue);
1936         assert(data);
1937
1938         l = strv_split_quoted(rvalue);
1939         if (!l)
1940                 return -ENOMEM;
1941
1942         k = strv_length(l);
1943         if (k != 2) {
1944                 log_error("[%s:%u] Failed to parse bandwidth value, ignoring: %s", filename, line, rvalue);
1945                 strv_free(l);
1946                 return 0;
1947         }
1948
1949         if (!path_is_absolute(l[0])) {
1950                 log_error("[%s:%u] Failed to parse block device node value, ignoring: %s", filename, line, rvalue);
1951                 strv_free(l);
1952                 return 0;
1953         }
1954
1955         if (parse_bytes(l[1], &bytes) < 0 || bytes <= 0) {
1956                 log_error("[%s:%u] Failed to parse block IO bandwith value, ignoring: %s", filename, line, rvalue);
1957                 strv_free(l);
1958                 return 0;
1959         }
1960
1961         r = asprintf(&t, "%s %llu", l[0], (unsigned long long) bytes);
1962         strv_free(l);
1963
1964         if (r < 0)
1965                 return -ENOMEM;
1966
1967         r = unit_add_cgroup_attribute(u, "blkio",
1968                                       streq(lvalue, "BlockIOReadBandwidth") ? "blkio.read_bps_device" : "blkio.write_bps_device",
1969                                       t, blkio_map);
1970         free(t);
1971
1972         if (r < 0) {
1973                 log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
1974                 return 0;
1975         }
1976
1977         return 0;
1978 }
1979
1980 int config_parse_unit_requires_mounts_for(
1981                 const char *filename,
1982                 unsigned line,
1983                 const char *section,
1984                 const char *lvalue,
1985                 int ltype,
1986                 const char *rvalue,
1987                 void *data,
1988                 void *userdata) {
1989
1990         Unit *u = userdata;
1991         int r;
1992         bool empty_before;
1993
1994         assert(filename);
1995         assert(lvalue);
1996         assert(rvalue);
1997         assert(data);
1998
1999         empty_before = !u->requires_mounts_for;
2000
2001         r = config_parse_path_strv(filename, line, section, lvalue, ltype, rvalue, data, userdata);
2002
2003         /* Make it easy to find units with requires_mounts set */
2004         if (empty_before && u->requires_mounts_for)
2005                 LIST_PREPEND(Unit, has_requires_mounts_for, u->manager->has_requires_mounts_for, u);
2006
2007         return r;
2008 }
2009
2010 int config_parse_documentation(
2011                 const char *filename,
2012                 unsigned line,
2013                 const char *section,
2014                 const char *lvalue,
2015                 int ltype,
2016                 const char *rvalue,
2017                 void *data,
2018                 void *userdata) {
2019
2020         Unit *u = userdata;
2021         int r;
2022         char **a, **b;
2023
2024         assert(filename);
2025         assert(lvalue);
2026         assert(rvalue);
2027         assert(u);
2028
2029         r = config_parse_unit_strv_printf(filename, line, section, lvalue, ltype, rvalue, data, userdata);
2030         if (r < 0)
2031                 return r;
2032
2033         for (a = b = u->documentation; a && *a; a++) {
2034
2035                 if (is_valid_documentation_url(*a))
2036                         *(b++) = *a;
2037                 else {
2038                         log_error("[%s:%u] Invalid URL, ignoring: %s", filename, line, *a);
2039                         free(*a);
2040                 }
2041         }
2042         *b = NULL;
2043
2044         return r;
2045 }
2046
2047 #define FOLLOW_MAX 8
2048
2049 static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
2050         unsigned c = 0;
2051         int fd, r;
2052         FILE *f;
2053         char *id = NULL;
2054
2055         assert(filename);
2056         assert(*filename);
2057         assert(_f);
2058         assert(names);
2059
2060         /* This will update the filename pointer if the loaded file is
2061          * reached by a symlink. The old string will be freed. */
2062
2063         for (;;) {
2064                 char *target, *name;
2065
2066                 if (c++ >= FOLLOW_MAX)
2067                         return -ELOOP;
2068
2069                 path_kill_slashes(*filename);
2070
2071                 /* Add the file name we are currently looking at to
2072                  * the names of this unit, but only if it is a valid
2073                  * unit name. */
2074                 name = path_get_file_name(*filename);
2075
2076                 if (unit_name_is_valid(name, true)) {
2077
2078                         id = set_get(names, name);
2079                         if (!id) {
2080                                 id = strdup(name);
2081                                 if (!id)
2082                                         return -ENOMEM;
2083
2084                                 r = set_put(names, id);
2085                                 if (r < 0) {
2086                                         free(id);
2087                                         return r;
2088                                 }
2089                         }
2090                 }
2091
2092                 /* Try to open the file name, but don't if its a symlink */
2093                 if ((fd = open(*filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW)) >= 0)
2094                         break;
2095
2096                 if (errno != ELOOP)
2097                         return -errno;
2098
2099                 /* Hmm, so this is a symlink. Let's read the name, and follow it manually */
2100                 if ((r = readlink_and_make_absolute(*filename, &target)) < 0)
2101                         return r;
2102
2103                 free(*filename);
2104                 *filename = target;
2105         }
2106
2107         if (!(f = fdopen(fd, "re"))) {
2108                 r = -errno;
2109                 close_nointr_nofail(fd);
2110                 return r;
2111         }
2112
2113         *_f = f;
2114         *_final = id;
2115         return 0;
2116 }
2117
2118 static int merge_by_names(Unit **u, Set *names, const char *id) {
2119         char *k;
2120         int r;
2121
2122         assert(u);
2123         assert(*u);
2124         assert(names);
2125
2126         /* Let's try to add in all symlink names we found */
2127         while ((k = set_steal_first(names))) {
2128
2129                 /* First try to merge in the other name into our
2130                  * unit */
2131                 if ((r = unit_merge_by_name(*u, k)) < 0) {
2132                         Unit *other;
2133
2134                         /* Hmm, we couldn't merge the other unit into
2135                          * ours? Then let's try it the other way
2136                          * round */
2137
2138                         other = manager_get_unit((*u)->manager, k);
2139                         free(k);
2140
2141                         if (other)
2142                                 if ((r = unit_merge(other, *u)) >= 0) {
2143                                         *u = other;
2144                                         return merge_by_names(u, names, NULL);
2145                                 }
2146
2147                         return r;
2148                 }
2149
2150                 if (id == k)
2151                         unit_choose_id(*u, id);
2152
2153                 free(k);
2154         }
2155
2156         return 0;
2157 }
2158
2159 static int load_from_path(Unit *u, const char *path) {
2160         int r;
2161         Set *symlink_names;
2162         FILE *f = NULL;
2163         char *filename = NULL, *id = NULL;
2164         Unit *merged;
2165         struct stat st;
2166
2167         assert(u);
2168         assert(path);
2169
2170         symlink_names = set_new(string_hash_func, string_compare_func);
2171         if (!symlink_names)
2172                 return -ENOMEM;
2173
2174         if (path_is_absolute(path)) {
2175
2176                 if (!(filename = strdup(path))) {
2177                         r = -ENOMEM;
2178                         goto finish;
2179                 }
2180
2181                 if ((r = open_follow(&filename, &f, symlink_names, &id)) < 0) {
2182                         free(filename);
2183                         filename = NULL;
2184
2185                         if (r != -ENOENT)
2186                                 goto finish;
2187                 }
2188
2189         } else  {
2190                 char **p;
2191
2192                 STRV_FOREACH(p, u->manager->lookup_paths.unit_path) {
2193
2194                         /* Instead of opening the path right away, we manually
2195                          * follow all symlinks and add their name to our unit
2196                          * name set while doing so */
2197                         if (!(filename = path_make_absolute(path, *p))) {
2198                                 r = -ENOMEM;
2199                                 goto finish;
2200                         }
2201
2202                         if (u->manager->unit_path_cache &&
2203                             !set_get(u->manager->unit_path_cache, filename))
2204                                 r = -ENOENT;
2205                         else
2206                                 r = open_follow(&filename, &f, symlink_names, &id);
2207
2208                         if (r < 0) {
2209                                 char *sn;
2210
2211                                 free(filename);
2212                                 filename = NULL;
2213
2214                                 if (r != -ENOENT)
2215                                         goto finish;
2216
2217                                 /* Empty the symlink names for the next run */
2218                                 while ((sn = set_steal_first(symlink_names)))
2219                                         free(sn);
2220
2221                                 continue;
2222                         }
2223
2224                         break;
2225                 }
2226         }
2227
2228         if (!filename) {
2229                 /* Hmm, no suitable file found? */
2230                 r = 0;
2231                 goto finish;
2232         }
2233
2234         merged = u;
2235         if ((r = merge_by_names(&merged, symlink_names, id)) < 0)
2236                 goto finish;
2237
2238         if (merged != u) {
2239                 u->load_state = UNIT_MERGED;
2240                 r = 0;
2241                 goto finish;
2242         }
2243
2244         zero(st);
2245         if (fstat(fileno(f), &st) < 0) {
2246                 r = -errno;
2247                 goto finish;
2248         }
2249
2250         if (null_or_empty(&st))
2251                 u->load_state = UNIT_MASKED;
2252         else {
2253                 /* Now, parse the file contents */
2254                 r = config_parse(filename, f, UNIT_VTABLE(u)->sections, config_item_perf_lookup, (void*) load_fragment_gperf_lookup, false, u);
2255                 if (r < 0)
2256                         goto finish;
2257
2258                 u->load_state = UNIT_LOADED;
2259         }
2260
2261         free(u->fragment_path);
2262         u->fragment_path = filename;
2263         filename = NULL;
2264
2265         u->fragment_mtime = timespec_load(&st.st_mtim);
2266
2267         if (u->source_path) {
2268                 if (stat(u->source_path, &st) >= 0)
2269                         u->source_mtime = timespec_load(&st.st_mtim);
2270                 else
2271                         u->source_mtime = 0;
2272         }
2273
2274         r = 0;
2275
2276 finish:
2277         set_free_free(symlink_names);
2278         free(filename);
2279
2280         if (f)
2281                 fclose(f);
2282
2283         return r;
2284 }
2285
2286 int unit_load_fragment(Unit *u) {
2287         int r;
2288         Iterator i;
2289         const char *t;
2290
2291         assert(u);
2292         assert(u->load_state == UNIT_STUB);
2293         assert(u->id);
2294
2295         /* First, try to find the unit under its id. We always look
2296          * for unit files in the default directories, to make it easy
2297          * to override things by placing things in /etc/systemd/system */
2298         if ((r = load_from_path(u, u->id)) < 0)
2299                 return r;
2300
2301         /* Try to find an alias we can load this with */
2302         if (u->load_state == UNIT_STUB)
2303                 SET_FOREACH(t, u->names, i) {
2304
2305                         if (t == u->id)
2306                                 continue;
2307
2308                         if ((r = load_from_path(u, t)) < 0)
2309                                 return r;
2310
2311                         if (u->load_state != UNIT_STUB)
2312                                 break;
2313                 }
2314
2315         /* And now, try looking for it under the suggested (originally linked) path */
2316         if (u->load_state == UNIT_STUB && u->fragment_path) {
2317
2318                 if ((r = load_from_path(u, u->fragment_path)) < 0)
2319                         return r;
2320
2321                 if (u->load_state == UNIT_STUB) {
2322                         /* Hmm, this didn't work? Then let's get rid
2323                          * of the fragment path stored for us, so that
2324                          * we don't point to an invalid location. */
2325                         free(u->fragment_path);
2326                         u->fragment_path = NULL;
2327                 }
2328         }
2329
2330         /* Look for a template */
2331         if (u->load_state == UNIT_STUB && u->instance) {
2332                 char *k;
2333
2334                 if (!(k = unit_name_template(u->id)))
2335                         return -ENOMEM;
2336
2337                 r = load_from_path(u, k);
2338                 free(k);
2339
2340                 if (r < 0)
2341                         return r;
2342
2343                 if (u->load_state == UNIT_STUB)
2344                         SET_FOREACH(t, u->names, i) {
2345
2346                                 if (t == u->id)
2347                                         continue;
2348
2349                                 if (!(k = unit_name_template(t)))
2350                                         return -ENOMEM;
2351
2352                                 r = load_from_path(u, k);
2353                                 free(k);
2354
2355                                 if (r < 0)
2356                                         return r;
2357
2358                                 if (u->load_state != UNIT_STUB)
2359                                         break;
2360                         }
2361         }
2362
2363         return 0;
2364 }
2365
2366 void unit_dump_config_items(FILE *f) {
2367         static const struct {
2368                 const ConfigParserCallback callback;
2369                 const char *rvalue;
2370         } table[] = {
2371                 { config_parse_int,                   "INTEGER" },
2372                 { config_parse_unsigned,              "UNSIGNED" },
2373                 { config_parse_bytes_size,            "SIZE" },
2374                 { config_parse_bool,                  "BOOLEAN" },
2375                 { config_parse_string,                "STRING" },
2376                 { config_parse_path,                  "PATH" },
2377                 { config_parse_unit_path_printf,      "PATH" },
2378                 { config_parse_strv,                  "STRING [...]" },
2379                 { config_parse_exec_nice,             "NICE" },
2380                 { config_parse_exec_oom_score_adjust, "OOMSCOREADJUST" },
2381                 { config_parse_exec_io_class,         "IOCLASS" },
2382                 { config_parse_exec_io_priority,      "IOPRIORITY" },
2383                 { config_parse_exec_cpu_sched_policy, "CPUSCHEDPOLICY" },
2384                 { config_parse_exec_cpu_sched_prio,   "CPUSCHEDPRIO" },
2385                 { config_parse_exec_cpu_affinity,     "CPUAFFINITY" },
2386                 { config_parse_mode,                  "MODE" },
2387                 { config_parse_unit_env_file,         "FILE" },
2388                 { config_parse_output,                "OUTPUT" },
2389                 { config_parse_input,                 "INPUT" },
2390                 { config_parse_facility,              "FACILITY" },
2391                 { config_parse_level,                 "LEVEL" },
2392                 { config_parse_exec_capabilities,     "CAPABILITIES" },
2393                 { config_parse_exec_secure_bits,      "SECUREBITS" },
2394                 { config_parse_bounding_set,          "BOUNDINGSET" },
2395                 { config_parse_limit,                 "LIMIT" },
2396                 { config_parse_unit_cgroup,           "CGROUP [...]" },
2397                 { config_parse_unit_deps,             "UNIT [...]" },
2398                 { config_parse_unit_names,            "UNIT [...]" },
2399                 { config_parse_exec,                  "PATH [ARGUMENT [...]]" },
2400                 { config_parse_service_type,          "SERVICETYPE" },
2401                 { config_parse_service_restart,       "SERVICERESTART" },
2402 #ifdef HAVE_SYSV_COMPAT
2403                 { config_parse_sysv_priority,         "SYSVPRIORITY" },
2404 #else
2405                 { config_parse_warn_compat,           "NOTSUPPORTED" },
2406 #endif
2407                 { config_parse_kill_mode,             "KILLMODE" },
2408                 { config_parse_kill_signal,           "SIGNAL" },
2409                 { config_parse_socket_listen,         "SOCKET [...]" },
2410                 { config_parse_socket_bind,           "SOCKETBIND" },
2411                 { config_parse_socket_bindtodevice,   "NETWORKINTERFACE" },
2412                 { config_parse_usec,                  "SECONDS" },
2413                 { config_parse_nsec,                  "NANOSECONDS" },
2414                 { config_parse_path_strv,             "PATH [...]" },
2415                 { config_parse_unit_requires_mounts_for, "PATH [...]" },
2416                 { config_parse_exec_mount_flags,      "MOUNTFLAG [...]" },
2417                 { config_parse_unit_string_printf,    "STRING" },
2418                 { config_parse_timer,                 "TIMER" },
2419                 { config_parse_timer_unit,            "NAME" },
2420                 { config_parse_path_spec,             "PATH" },
2421                 { config_parse_path_unit,             "UNIT" },
2422                 { config_parse_notify_access,         "ACCESS" },
2423                 { config_parse_ip_tos,                "TOS" },
2424                 { config_parse_unit_condition_path,   "CONDITION" },
2425                 { config_parse_unit_condition_string, "CONDITION" },
2426                 { config_parse_unit_condition_null,   "CONDITION" },
2427         };
2428
2429         const char *prev = NULL;
2430         const char *i;
2431
2432         assert(f);
2433
2434         NULSTR_FOREACH(i, load_fragment_gperf_nulstr) {
2435                 const char *rvalue = "OTHER", *lvalue;
2436                 unsigned j;
2437                 size_t prefix_len;
2438                 const char *dot;
2439                 const ConfigPerfItem *p;
2440
2441                 assert_se(p = load_fragment_gperf_lookup(i, strlen(i)));
2442
2443                 dot = strchr(i, '.');
2444                 lvalue = dot ? dot + 1 : i;
2445                 prefix_len = dot-i;
2446
2447                 if (dot)
2448                         if (!prev || strncmp(prev, i, prefix_len+1) != 0) {
2449                                 if (prev)
2450                                         fputc('\n', f);
2451
2452                                 fprintf(f, "[%.*s]\n", (int) prefix_len, i);
2453                         }
2454
2455                 for (j = 0; j < ELEMENTSOF(table); j++)
2456                         if (p->parse == table[j].callback) {
2457                                 rvalue = table[j].rvalue;
2458                                 break;
2459                         }
2460
2461                 fprintf(f, "%s=%s\n", lvalue, rvalue);
2462                 prev = i;
2463         }
2464 }