]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - src/shared/install.c
exec-util,conf-files: skip non-executable files in execute_directories()
[thirdparty/systemd.git] / src / shared / install.c
... / ...
CommitLineData
1/***
2 This file is part of systemd.
3
4 Copyright 2011 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty <of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18***/
19
20#include <dirent.h>
21#include <errno.h>
22#include <fcntl.h>
23#include <fnmatch.h>
24#include <limits.h>
25#include <stddef.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <sys/stat.h>
30#include <unistd.h>
31
32#include "alloc-util.h"
33#include "conf-files.h"
34#include "conf-parser.h"
35#include "dirent-util.h"
36#include "extract-word.h"
37#include "fd-util.h"
38#include "fileio.h"
39#include "fs-util.h"
40#include "hashmap.h"
41#include "install-printf.h"
42#include "install.h"
43#include "locale-util.h"
44#include "log.h"
45#include "macro.h"
46#include "mkdir.h"
47#include "path-lookup.h"
48#include "path-util.h"
49#include "rm-rf.h"
50#include "set.h"
51#include "special.h"
52#include "stat-util.h"
53#include "string-table.h"
54#include "string-util.h"
55#include "strv.h"
56#include "unit-name.h"
57
58#define UNIT_FILE_FOLLOW_SYMLINK_MAX 64
59
60typedef enum SearchFlags {
61 SEARCH_LOAD = 1,
62 SEARCH_FOLLOW_CONFIG_SYMLINKS = 2,
63} SearchFlags;
64
65typedef struct {
66 OrderedHashmap *will_process;
67 OrderedHashmap *have_processed;
68} InstallContext;
69
70typedef enum {
71 PRESET_UNKNOWN,
72 PRESET_ENABLE,
73 PRESET_DISABLE,
74} PresetAction;
75
76typedef struct {
77 char *pattern;
78 PresetAction action;
79} PresetRule;
80
81typedef struct {
82 PresetRule *rules;
83 size_t n_rules;
84} Presets;
85
86static inline void presets_freep(Presets *p) {
87 size_t i;
88
89 if (!p)
90 return;
91
92 for (i = 0; i < p->n_rules; i++)
93 free(p->rules[i].pattern);
94
95 free(p->rules);
96 p->n_rules = 0;
97}
98
99static int unit_file_lookup_state(UnitFileScope scope, const LookupPaths *paths, const char *name, UnitFileState *ret);
100
101bool unit_type_may_alias(UnitType type) {
102 return IN_SET(type,
103 UNIT_SERVICE,
104 UNIT_SOCKET,
105 UNIT_TARGET,
106 UNIT_DEVICE,
107 UNIT_TIMER,
108 UNIT_PATH);
109}
110
111bool unit_type_may_template(UnitType type) {
112 return IN_SET(type,
113 UNIT_SERVICE,
114 UNIT_SOCKET,
115 UNIT_TARGET,
116 UNIT_TIMER,
117 UNIT_PATH);
118}
119
120static const char *unit_file_type_table[_UNIT_FILE_TYPE_MAX] = {
121 [UNIT_FILE_TYPE_REGULAR] = "regular",
122 [UNIT_FILE_TYPE_SYMLINK] = "symlink",
123 [UNIT_FILE_TYPE_MASKED] = "masked",
124};
125
126DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(unit_file_type, UnitFileType);
127
128static int in_search_path(const LookupPaths *p, const char *path) {
129 _cleanup_free_ char *parent = NULL;
130 char **i;
131
132 assert(path);
133
134 parent = dirname_malloc(path);
135 if (!parent)
136 return -ENOMEM;
137
138 STRV_FOREACH(i, p->search_path)
139 if (path_equal(parent, *i))
140 return true;
141
142 return false;
143}
144
145static const char* skip_root(const LookupPaths *p, const char *path) {
146 char *e;
147
148 assert(p);
149 assert(path);
150
151 if (!p->root_dir)
152 return path;
153
154 e = path_startswith(path, p->root_dir);
155 if (!e)
156 return NULL;
157
158 /* Make sure the returned path starts with a slash */
159 if (e[0] != '/') {
160 if (e == path || e[-1] != '/')
161 return NULL;
162
163 e--;
164 }
165
166 return e;
167}
168
169static int path_is_generator(const LookupPaths *p, const char *path) {
170 _cleanup_free_ char *parent = NULL;
171
172 assert(p);
173 assert(path);
174
175 parent = dirname_malloc(path);
176 if (!parent)
177 return -ENOMEM;
178
179 return path_equal_ptr(parent, p->generator) ||
180 path_equal_ptr(parent, p->generator_early) ||
181 path_equal_ptr(parent, p->generator_late);
182}
183
184static int path_is_transient(const LookupPaths *p, const char *path) {
185 _cleanup_free_ char *parent = NULL;
186
187 assert(p);
188 assert(path);
189
190 parent = dirname_malloc(path);
191 if (!parent)
192 return -ENOMEM;
193
194 return path_equal_ptr(parent, p->transient);
195}
196
197static int path_is_control(const LookupPaths *p, const char *path) {
198 _cleanup_free_ char *parent = NULL;
199
200 assert(p);
201 assert(path);
202
203 parent = dirname_malloc(path);
204 if (!parent)
205 return -ENOMEM;
206
207 return path_equal_ptr(parent, p->persistent_control) ||
208 path_equal_ptr(parent, p->runtime_control);
209}
210
211static int path_is_config(const LookupPaths *p, const char *path, bool check_parent) {
212 _cleanup_free_ char *parent = NULL;
213
214 assert(p);
215 assert(path);
216
217 /* Note that we do *not* have generic checks for /etc or /run in place, since with
218 * them we couldn't discern configuration from transient or generated units */
219
220 if (check_parent) {
221 parent = dirname_malloc(path);
222 if (!parent)
223 return -ENOMEM;
224
225 path = parent;
226 }
227
228 return path_equal_ptr(path, p->persistent_config) ||
229 path_equal_ptr(path, p->runtime_config);
230}
231
232static int path_is_runtime(const LookupPaths *p, const char *path, bool check_parent) {
233 _cleanup_free_ char *parent = NULL;
234 const char *rpath;
235
236 assert(p);
237 assert(path);
238
239 /* Everything in /run is considered runtime. On top of that we also add
240 * explicit checks for the various runtime directories, as safety net. */
241
242 rpath = skip_root(p, path);
243 if (rpath && path_startswith(rpath, "/run"))
244 return true;
245
246 if (check_parent) {
247 parent = dirname_malloc(path);
248 if (!parent)
249 return -ENOMEM;
250
251 path = parent;
252 }
253
254 return path_equal_ptr(path, p->runtime_config) ||
255 path_equal_ptr(path, p->generator) ||
256 path_equal_ptr(path, p->generator_early) ||
257 path_equal_ptr(path, p->generator_late) ||
258 path_equal_ptr(path, p->transient) ||
259 path_equal_ptr(path, p->runtime_control);
260}
261
262static int path_is_vendor(const LookupPaths *p, const char *path) {
263 const char *rpath;
264
265 assert(p);
266 assert(path);
267
268 rpath = skip_root(p, path);
269 if (!rpath)
270 return 0;
271
272 if (path_startswith(rpath, "/usr"))
273 return true;
274
275#ifdef HAVE_SPLIT_USR
276 if (path_startswith(rpath, "/lib"))
277 return true;
278#endif
279
280 return path_equal(rpath, SYSTEM_DATA_UNIT_PATH);
281}
282
283int unit_file_changes_add(
284 UnitFileChange **changes,
285 unsigned *n_changes,
286 UnitFileChangeType type,
287 const char *path,
288 const char *source) {
289
290 _cleanup_free_ char *p = NULL, *s = NULL;
291 UnitFileChange *c;
292
293 assert(path);
294 assert(!changes == !n_changes);
295
296 if (!changes)
297 return 0;
298
299 c = realloc(*changes, (*n_changes + 1) * sizeof(UnitFileChange));
300 if (!c)
301 return -ENOMEM;
302 *changes = c;
303
304 p = strdup(path);
305 if (source)
306 s = strdup(source);
307
308 if (!p || (source && !s))
309 return -ENOMEM;
310
311 path_kill_slashes(p);
312 if (s)
313 path_kill_slashes(s);
314
315 c[*n_changes] = (UnitFileChange) { type, p, s };
316 p = s = NULL;
317 (*n_changes) ++;
318 return 0;
319}
320
321void unit_file_changes_free(UnitFileChange *changes, unsigned n_changes) {
322 unsigned i;
323
324 assert(changes || n_changes == 0);
325
326 for (i = 0; i < n_changes; i++) {
327 free(changes[i].path);
328 free(changes[i].source);
329 }
330
331 free(changes);
332}
333
334void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *changes, unsigned n_changes, bool quiet) {
335 unsigned i;
336 bool logged = false;
337
338 assert(changes || n_changes == 0);
339 /* If verb is not specified, errors are not allowed! */
340 assert(verb || r >= 0);
341
342 for (i = 0; i < n_changes; i++) {
343 assert(verb || changes[i].type >= 0);
344
345 switch(changes[i].type) {
346 case UNIT_FILE_SYMLINK:
347 if (!quiet)
348 log_info("Created symlink %s %s %s.",
349 changes[i].path,
350 special_glyph(ARROW),
351 changes[i].source);
352 break;
353 case UNIT_FILE_UNLINK:
354 if (!quiet)
355 log_info("Removed %s.", changes[i].path);
356 break;
357 case UNIT_FILE_IS_MASKED:
358 if (!quiet)
359 log_info("Unit %s is masked, ignoring.", changes[i].path);
360 break;
361 case UNIT_FILE_IS_DANGLING:
362 if (!quiet)
363 log_info("Unit %s is an alias to a unit that is not present, ignoring.",
364 changes[i].path);
365 break;
366 case -EEXIST:
367 if (changes[i].source)
368 log_error_errno(changes[i].type,
369 "Failed to %s unit, file %s already exists and is a symlink to %s.",
370 verb, changes[i].path, changes[i].source);
371 else
372 log_error_errno(changes[i].type,
373 "Failed to %s unit, file %s already exists.",
374 verb, changes[i].path);
375 logged = true;
376 break;
377 case -ERFKILL:
378 log_error_errno(changes[i].type, "Failed to %s unit, unit %s is masked.",
379 verb, changes[i].path);
380 logged = true;
381 break;
382 case -EADDRNOTAVAIL:
383 log_error_errno(changes[i].type, "Failed to %s unit, unit %s is transient or generated.",
384 verb, changes[i].path);
385 logged = true;
386 break;
387 case -ELOOP:
388 log_error_errno(changes[i].type, "Failed to %s unit, refusing to operate on linked unit file %s",
389 verb, changes[i].path);
390 logged = true;
391 break;
392
393 case -ENOENT:
394 log_error_errno(changes[i].type, "Failed to %s unit, unit %s does not exist.", verb, changes[i].path);
395 logged = true;
396 break;
397
398 default:
399 assert(changes[i].type < 0);
400 log_error_errno(changes[i].type, "Failed to %s unit, file %s: %m.",
401 verb, changes[i].path);
402 logged = true;
403 }
404 }
405
406 if (r < 0 && !logged)
407 log_error_errno(r, "Failed to %s: %m.", verb);
408}
409
410/**
411 * Checks if two paths or symlinks from wd are the same, when root is the root of the filesystem.
412 * wc should be the full path in the host file system.
413 */
414static bool chroot_symlinks_same(const char *root, const char *wd, const char *a, const char *b) {
415 assert(path_is_absolute(wd));
416
417 /* This will give incorrect results if the paths are relative and go outside
418 * of the chroot. False negatives are possible. */
419
420 if (!root)
421 root = "/";
422
423 a = strjoina(path_is_absolute(a) ? root : wd, "/", a);
424 b = strjoina(path_is_absolute(b) ? root : wd, "/", b);
425 return path_equal_or_files_same(a, b, 0);
426}
427
428static int create_symlink(
429 const LookupPaths *paths,
430 const char *old_path,
431 const char *new_path,
432 bool force,
433 UnitFileChange **changes,
434 unsigned *n_changes) {
435
436 _cleanup_free_ char *dest = NULL, *dirname = NULL;
437 const char *rp;
438 int r;
439
440 assert(old_path);
441 assert(new_path);
442
443 rp = skip_root(paths, old_path);
444 if (rp)
445 old_path = rp;
446
447 /* Actually create a symlink, and remember that we did. Is
448 * smart enough to check if there's already a valid symlink in
449 * place.
450 *
451 * Returns 1 if a symlink was created or already exists and points to
452 * the right place, or negative on error.
453 */
454
455 mkdir_parents_label(new_path, 0755);
456
457 if (symlink(old_path, new_path) >= 0) {
458 unit_file_changes_add(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
459 return 1;
460 }
461
462 if (errno != EEXIST) {
463 unit_file_changes_add(changes, n_changes, -errno, new_path, NULL);
464 return -errno;
465 }
466
467 r = readlink_malloc(new_path, &dest);
468 if (r < 0) {
469 /* translate EINVAL (non-symlink exists) to EEXIST */
470 if (r == -EINVAL)
471 r = -EEXIST;
472
473 unit_file_changes_add(changes, n_changes, r, new_path, NULL);
474 return r;
475 }
476
477 dirname = dirname_malloc(new_path);
478 if (!dirname)
479 return -ENOMEM;
480
481 if (chroot_symlinks_same(paths->root_dir, dirname, dest, old_path))
482 return 1;
483
484 if (!force) {
485 unit_file_changes_add(changes, n_changes, -EEXIST, new_path, dest);
486 return -EEXIST;
487 }
488
489 r = symlink_atomic(old_path, new_path);
490 if (r < 0) {
491 unit_file_changes_add(changes, n_changes, r, new_path, NULL);
492 return r;
493 }
494
495 unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL);
496 unit_file_changes_add(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
497
498 return 1;
499}
500
501static int mark_symlink_for_removal(
502 Set **remove_symlinks_to,
503 const char *p) {
504
505 char *n;
506 int r;
507
508 assert(p);
509
510 r = set_ensure_allocated(remove_symlinks_to, &string_hash_ops);
511 if (r < 0)
512 return r;
513
514 n = strdup(p);
515 if (!n)
516 return -ENOMEM;
517
518 path_kill_slashes(n);
519
520 r = set_consume(*remove_symlinks_to, n);
521 if (r == -EEXIST)
522 return 0;
523 if (r < 0)
524 return r;
525
526 return 1;
527}
528
529static int remove_marked_symlinks_fd(
530 Set *remove_symlinks_to,
531 int fd,
532 const char *path,
533 const char *config_path,
534 const LookupPaths *lp,
535 bool dry_run,
536 bool *restart,
537 UnitFileChange **changes,
538 unsigned *n_changes) {
539
540 _cleanup_closedir_ DIR *d = NULL;
541 struct dirent *de;
542 int r = 0;
543
544 assert(remove_symlinks_to);
545 assert(fd >= 0);
546 assert(path);
547 assert(config_path);
548 assert(lp);
549 assert(restart);
550
551 d = fdopendir(fd);
552 if (!d) {
553 safe_close(fd);
554 return -errno;
555 }
556
557 rewinddir(d);
558
559 FOREACH_DIRENT(de, d, return -errno) {
560
561 dirent_ensure_type(d, de);
562
563 if (de->d_type == DT_DIR) {
564 _cleanup_free_ char *p = NULL;
565 int nfd, q;
566
567 nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
568 if (nfd < 0) {
569 if (errno == ENOENT)
570 continue;
571
572 if (r == 0)
573 r = -errno;
574 continue;
575 }
576
577 p = path_make_absolute(de->d_name, path);
578 if (!p) {
579 safe_close(nfd);
580 return -ENOMEM;
581 }
582
583 /* This will close nfd, regardless whether it succeeds or not */
584 q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, lp, dry_run, restart, changes, n_changes);
585 if (q < 0 && r == 0)
586 r = q;
587
588 } else if (de->d_type == DT_LNK) {
589 _cleanup_free_ char *p = NULL, *dest = NULL;
590 const char *rp;
591 bool found;
592 int q;
593
594 if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
595 continue;
596
597 p = path_make_absolute(de->d_name, path);
598 if (!p)
599 return -ENOMEM;
600 path_kill_slashes(p);
601
602 q = readlink_malloc(p, &dest);
603 if (q == -ENOENT)
604 continue;
605 if (q < 0) {
606 if (r == 0)
607 r = q;
608 continue;
609 }
610
611 /* We remove all links pointing to a file or path that is marked, as well as all files sharing
612 * the same name as a file that is marked. */
613
614 found = set_contains(remove_symlinks_to, dest) ||
615 set_contains(remove_symlinks_to, basename(dest)) ||
616 set_contains(remove_symlinks_to, de->d_name);
617
618 if (!found)
619 continue;
620
621 if (!dry_run) {
622 if (unlinkat(fd, de->d_name, 0) < 0 && errno != ENOENT) {
623 if (r == 0)
624 r = -errno;
625 unit_file_changes_add(changes, n_changes, -errno, p, NULL);
626 continue;
627 }
628
629 (void) rmdir_parents(p, config_path);
630 }
631
632 unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, p, NULL);
633
634 /* Now, remember the full path (but with the root prefix removed) of
635 * the symlink we just removed, and remove any symlinks to it, too. */
636
637 rp = skip_root(lp, p);
638 q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: p);
639 if (q < 0)
640 return q;
641 if (q > 0 && !dry_run)
642 *restart = true;
643 }
644 }
645
646 return r;
647}
648
649static int remove_marked_symlinks(
650 Set *remove_symlinks_to,
651 const char *config_path,
652 const LookupPaths *lp,
653 bool dry_run,
654 UnitFileChange **changes,
655 unsigned *n_changes) {
656
657 _cleanup_close_ int fd = -1;
658 bool restart;
659 int r = 0;
660
661 assert(config_path);
662 assert(lp);
663
664 if (set_size(remove_symlinks_to) <= 0)
665 return 0;
666
667 fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC);
668 if (fd < 0)
669 return errno == ENOENT ? 0 : -errno;
670
671 do {
672 int q, cfd;
673 restart = false;
674
675 cfd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
676 if (cfd < 0)
677 return -errno;
678
679 /* This takes possession of cfd and closes it */
680 q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, lp, dry_run, &restart, changes, n_changes);
681 if (r == 0)
682 r = q;
683 } while (restart);
684
685 return r;
686}
687
688static int find_symlinks_fd(
689 const char *root_dir,
690 const char *name,
691 int fd,
692 const char *path,
693 const char *config_path,
694 bool *same_name_link) {
695
696 _cleanup_closedir_ DIR *d = NULL;
697 struct dirent *de;
698 int r = 0;
699
700 assert(name);
701 assert(fd >= 0);
702 assert(path);
703 assert(config_path);
704 assert(same_name_link);
705
706 d = fdopendir(fd);
707 if (!d) {
708 safe_close(fd);
709 return -errno;
710 }
711
712 FOREACH_DIRENT(de, d, return -errno) {
713
714 dirent_ensure_type(d, de);
715
716 if (de->d_type == DT_DIR) {
717 _cleanup_free_ char *p = NULL;
718 int nfd, q;
719
720 nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
721 if (nfd < 0) {
722 if (errno == ENOENT)
723 continue;
724
725 if (r == 0)
726 r = -errno;
727 continue;
728 }
729
730 p = path_make_absolute(de->d_name, path);
731 if (!p) {
732 safe_close(nfd);
733 return -ENOMEM;
734 }
735
736 /* This will close nfd, regardless whether it succeeds or not */
737 q = find_symlinks_fd(root_dir, name, nfd, p, config_path, same_name_link);
738 if (q > 0)
739 return 1;
740 if (r == 0)
741 r = q;
742
743 } else if (de->d_type == DT_LNK) {
744 _cleanup_free_ char *p = NULL, *dest = NULL;
745 bool found_path, found_dest, b = false;
746 int q;
747
748 /* Acquire symlink name */
749 p = path_make_absolute(de->d_name, path);
750 if (!p)
751 return -ENOMEM;
752
753 /* Acquire symlink destination */
754 q = readlink_malloc(p, &dest);
755 if (q == -ENOENT)
756 continue;
757 if (q < 0) {
758 if (r == 0)
759 r = q;
760 continue;
761 }
762
763 /* Make absolute */
764 if (!path_is_absolute(dest)) {
765 char *x;
766
767 x = prefix_root(root_dir, dest);
768 if (!x)
769 return -ENOMEM;
770
771 free(dest);
772 dest = x;
773 }
774
775 /* Check if the symlink itself matches what we
776 * are looking for */
777 if (path_is_absolute(name))
778 found_path = path_equal(p, name);
779 else
780 found_path = streq(de->d_name, name);
781
782 /* Check if what the symlink points to
783 * matches what we are looking for */
784 if (path_is_absolute(name))
785 found_dest = path_equal(dest, name);
786 else
787 found_dest = streq(basename(dest), name);
788
789 if (found_path && found_dest) {
790 _cleanup_free_ char *t = NULL;
791
792 /* Filter out same name links in the main
793 * config path */
794 t = path_make_absolute(name, config_path);
795 if (!t)
796 return -ENOMEM;
797
798 b = path_equal(t, p);
799 }
800
801 if (b)
802 *same_name_link = true;
803 else if (found_path || found_dest)
804 return 1;
805 }
806 }
807
808 return r;
809}
810
811static int find_symlinks(
812 const char *root_dir,
813 const char *name,
814 const char *config_path,
815 bool *same_name_link) {
816
817 int fd;
818
819 assert(name);
820 assert(config_path);
821 assert(same_name_link);
822
823 fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC);
824 if (fd < 0) {
825 if (IN_SET(errno, ENOENT, ENOTDIR, EACCES))
826 return 0;
827 return -errno;
828 }
829
830 /* This takes possession of fd and closes it */
831 return find_symlinks_fd(root_dir, name, fd, config_path, config_path, same_name_link);
832}
833
834static int find_symlinks_in_scope(
835 const LookupPaths *paths,
836 const char *name,
837 UnitFileState *state) {
838
839 bool same_name_link_runtime = false, same_name_link_config = false;
840 bool enabled_in_runtime = false, enabled_at_all = false;
841 char **p;
842 int r;
843
844 assert(paths);
845 assert(name);
846
847 STRV_FOREACH(p, paths->search_path) {
848 bool same_name_link = false;
849
850 r = find_symlinks(paths->root_dir, name, *p, &same_name_link);
851 if (r < 0)
852 return r;
853 if (r > 0) {
854 /* We found symlinks in this dir? Yay! Let's see where precisely it is enabled. */
855
856 r = path_is_config(paths, *p, false);
857 if (r < 0)
858 return r;
859 if (r > 0) {
860 /* This is the best outcome, let's return it immediately. */
861 *state = UNIT_FILE_ENABLED;
862 return 1;
863 }
864
865 r = path_is_runtime(paths, *p, false);
866 if (r < 0)
867 return r;
868 if (r > 0)
869 enabled_in_runtime = true;
870 else
871 enabled_at_all = true;
872
873 } else if (same_name_link) {
874
875 r = path_is_config(paths, *p, false);
876 if (r < 0)
877 return r;
878 if (r > 0)
879 same_name_link_config = true;
880 else {
881 r = path_is_runtime(paths, *p, false);
882 if (r < 0)
883 return r;
884 if (r > 0)
885 same_name_link_runtime = true;
886 }
887 }
888 }
889
890 if (enabled_in_runtime) {
891 *state = UNIT_FILE_ENABLED_RUNTIME;
892 return 1;
893 }
894
895 /* Here's a special rule: if the unit we are looking for is an instance, and it symlinked in the search path
896 * outside of runtime and configuration directory, then we consider it statically enabled. Note we do that only
897 * for instance, not for regular names, as those are merely aliases, while instances explicitly instantiate
898 * something, and hence are a much stronger concept. */
899 if (enabled_at_all && unit_name_is_valid(name, UNIT_NAME_INSTANCE)) {
900 *state = UNIT_FILE_STATIC;
901 return 1;
902 }
903
904 /* Hmm, we didn't find it, but maybe we found the same name
905 * link? */
906 if (same_name_link_config) {
907 *state = UNIT_FILE_LINKED;
908 return 1;
909 }
910 if (same_name_link_runtime) {
911 *state = UNIT_FILE_LINKED_RUNTIME;
912 return 1;
913 }
914
915 return 0;
916}
917
918static void install_info_free(UnitFileInstallInfo *i) {
919
920 if (!i)
921 return;
922
923 free(i->name);
924 free(i->path);
925 strv_free(i->aliases);
926 strv_free(i->wanted_by);
927 strv_free(i->required_by);
928 strv_free(i->also);
929 free(i->default_instance);
930 free(i->symlink_target);
931 free(i);
932}
933
934static OrderedHashmap* install_info_hashmap_free(OrderedHashmap *m) {
935 UnitFileInstallInfo *i;
936
937 if (!m)
938 return NULL;
939
940 while ((i = ordered_hashmap_steal_first(m)))
941 install_info_free(i);
942
943 return ordered_hashmap_free(m);
944}
945
946static void install_context_done(InstallContext *c) {
947 assert(c);
948
949 c->will_process = install_info_hashmap_free(c->will_process);
950 c->have_processed = install_info_hashmap_free(c->have_processed);
951}
952
953static UnitFileInstallInfo *install_info_find(InstallContext *c, const char *name) {
954 UnitFileInstallInfo *i;
955
956 i = ordered_hashmap_get(c->have_processed, name);
957 if (i)
958 return i;
959
960 return ordered_hashmap_get(c->will_process, name);
961}
962
963static int install_info_may_process(
964 UnitFileInstallInfo *i,
965 const LookupPaths *paths,
966 UnitFileChange **changes,
967 unsigned *n_changes) {
968 assert(i);
969 assert(paths);
970
971 /* Checks whether the loaded unit file is one we should process, or is masked,
972 * transient or generated and thus not subject to enable/disable operations. */
973
974 if (i->type == UNIT_FILE_TYPE_MASKED) {
975 unit_file_changes_add(changes, n_changes, -ERFKILL, i->path, NULL);
976 return -ERFKILL;
977 }
978 if (path_is_generator(paths, i->path) ||
979 path_is_transient(paths, i->path)) {
980 unit_file_changes_add(changes, n_changes, -EADDRNOTAVAIL, i->path, NULL);
981 return -EADDRNOTAVAIL;
982 }
983
984 return 0;
985}
986
987/**
988 * Adds a new UnitFileInstallInfo entry under name in the InstallContext.will_process
989 * hashmap, or retrieves the existing one if already present.
990 *
991 * Returns negative on error, 0 if the unit was already known, 1 otherwise.
992 */
993static int install_info_add(
994 InstallContext *c,
995 const char *name,
996 const char *path,
997 bool auxiliary,
998 UnitFileInstallInfo **ret) {
999
1000 UnitFileInstallInfo *i = NULL;
1001 int r;
1002
1003 assert(c);
1004 assert(name || path);
1005
1006 if (!name)
1007 name = basename(path);
1008
1009 if (!unit_name_is_valid(name, UNIT_NAME_ANY))
1010 return -EINVAL;
1011
1012 i = install_info_find(c, name);
1013 if (i) {
1014 i->auxiliary = i->auxiliary && auxiliary;
1015
1016 if (ret)
1017 *ret = i;
1018 return 0;
1019 }
1020
1021 r = ordered_hashmap_ensure_allocated(&c->will_process, &string_hash_ops);
1022 if (r < 0)
1023 return r;
1024
1025 i = new0(UnitFileInstallInfo, 1);
1026 if (!i)
1027 return -ENOMEM;
1028 i->type = _UNIT_FILE_TYPE_INVALID;
1029 i->auxiliary = auxiliary;
1030
1031 i->name = strdup(name);
1032 if (!i->name) {
1033 r = -ENOMEM;
1034 goto fail;
1035 }
1036
1037 if (path) {
1038 i->path = strdup(path);
1039 if (!i->path) {
1040 r = -ENOMEM;
1041 goto fail;
1042 }
1043 }
1044
1045 r = ordered_hashmap_put(c->will_process, i->name, i);
1046 if (r < 0)
1047 goto fail;
1048
1049 if (ret)
1050 *ret = i;
1051
1052 return 1;
1053
1054fail:
1055 install_info_free(i);
1056 return r;
1057}
1058
1059static int config_parse_alias(
1060 const char *unit,
1061 const char *filename,
1062 unsigned line,
1063 const char *section,
1064 unsigned section_line,
1065 const char *lvalue,
1066 int ltype,
1067 const char *rvalue,
1068 void *data,
1069 void *userdata) {
1070
1071 const char *name;
1072 UnitType type;
1073
1074 assert(filename);
1075 assert(lvalue);
1076 assert(rvalue);
1077
1078 name = basename(filename);
1079 type = unit_name_to_type(name);
1080 if (!unit_type_may_alias(type))
1081 return log_syntax(unit, LOG_WARNING, filename, line, 0,
1082 "Alias= is not allowed for %s units, ignoring.",
1083 unit_type_to_string(type));
1084
1085 return config_parse_strv(unit, filename, line, section, section_line,
1086 lvalue, ltype, rvalue, data, userdata);
1087}
1088
1089static int config_parse_also(
1090 const char *unit,
1091 const char *filename,
1092 unsigned line,
1093 const char *section,
1094 unsigned section_line,
1095 const char *lvalue,
1096 int ltype,
1097 const char *rvalue,
1098 void *data,
1099 void *userdata) {
1100
1101 UnitFileInstallInfo *info = userdata, *alsoinfo = NULL;
1102 InstallContext *c = data;
1103 int r;
1104
1105 assert(filename);
1106 assert(lvalue);
1107 assert(rvalue);
1108
1109 for (;;) {
1110 _cleanup_free_ char *word = NULL, *printed = NULL;
1111
1112 r = extract_first_word(&rvalue, &word, NULL, 0);
1113 if (r < 0)
1114 return r;
1115 if (r == 0)
1116 break;
1117
1118 r = install_full_printf(info, word, &printed);
1119 if (r < 0)
1120 return r;
1121
1122 if (!unit_name_is_valid(printed, UNIT_NAME_ANY))
1123 return -EINVAL;
1124
1125 r = install_info_add(c, printed, NULL, true, &alsoinfo);
1126 if (r < 0)
1127 return r;
1128
1129 r = strv_push(&info->also, printed);
1130 if (r < 0)
1131 return r;
1132
1133 printed = NULL;
1134 }
1135
1136 return 0;
1137}
1138
1139static int config_parse_default_instance(
1140 const char *unit,
1141 const char *filename,
1142 unsigned line,
1143 const char *section,
1144 unsigned section_line,
1145 const char *lvalue,
1146 int ltype,
1147 const char *rvalue,
1148 void *data,
1149 void *userdata) {
1150
1151 UnitFileInstallInfo *i = data;
1152 const char *name;
1153 _cleanup_free_ char *printed = NULL;
1154 int r;
1155
1156 assert(filename);
1157 assert(lvalue);
1158 assert(rvalue);
1159
1160 name = basename(filename);
1161 if (unit_name_is_valid(name, UNIT_NAME_INSTANCE))
1162 /* When enabling an instance, we might be using a template unit file,
1163 * but we should ignore DefaultInstance silently. */
1164 return 0;
1165 if (!unit_name_is_valid(name, UNIT_NAME_TEMPLATE))
1166 return log_syntax(unit, LOG_WARNING, filename, line, 0,
1167 "DefaultInstance= only makes sense for template units, ignoring.");
1168
1169 r = install_full_printf(i, rvalue, &printed);
1170 if (r < 0)
1171 return r;
1172
1173 if (!unit_instance_is_valid(printed))
1174 return -EINVAL;
1175
1176 return free_and_replace(i->default_instance, printed);
1177}
1178
1179static int unit_file_load(
1180 InstallContext *c,
1181 UnitFileInstallInfo *info,
1182 const char *path,
1183 SearchFlags flags) {
1184
1185 const ConfigTableItem items[] = {
1186 { "Install", "Alias", config_parse_alias, 0, &info->aliases },
1187 { "Install", "WantedBy", config_parse_strv, 0, &info->wanted_by },
1188 { "Install", "RequiredBy", config_parse_strv, 0, &info->required_by },
1189 { "Install", "DefaultInstance", config_parse_default_instance, 0, info },
1190 { "Install", "Also", config_parse_also, 0, c },
1191 {}
1192 };
1193
1194 const char *name;
1195 UnitType type;
1196 _cleanup_fclose_ FILE *f = NULL;
1197 _cleanup_close_ int fd = -1;
1198 struct stat st;
1199 int r;
1200
1201 assert(info);
1202 assert(path);
1203
1204 name = basename(path);
1205 type = unit_name_to_type(name);
1206 if (unit_name_is_valid(name, UNIT_NAME_TEMPLATE|UNIT_NAME_INSTANCE) &&
1207 !unit_type_may_template(type))
1208 return log_error_errno(EINVAL, "Unit type %s cannot be templated.", unit_type_to_string(type));
1209
1210 if (!(flags & SEARCH_LOAD)) {
1211 r = lstat(path, &st);
1212 if (r < 0)
1213 return -errno;
1214
1215 if (null_or_empty(&st))
1216 info->type = UNIT_FILE_TYPE_MASKED;
1217 else if (S_ISREG(st.st_mode))
1218 info->type = UNIT_FILE_TYPE_REGULAR;
1219 else if (S_ISLNK(st.st_mode))
1220 return -ELOOP;
1221 else if (S_ISDIR(st.st_mode))
1222 return -EISDIR;
1223 else
1224 return -ENOTTY;
1225
1226 return 0;
1227 }
1228
1229 /* c is only needed if we actually load the file */
1230 assert(c);
1231
1232 fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
1233 if (fd < 0)
1234 return -errno;
1235 if (fstat(fd, &st) < 0)
1236 return -errno;
1237 if (null_or_empty(&st)) {
1238 info->type = UNIT_FILE_TYPE_MASKED;
1239 return 0;
1240 }
1241 if (S_ISDIR(st.st_mode))
1242 return -EISDIR;
1243 if (!S_ISREG(st.st_mode))
1244 return -ENOTTY;
1245
1246 f = fdopen(fd, "re");
1247 if (!f)
1248 return -errno;
1249 fd = -1;
1250
1251 r = config_parse(NULL, path, f,
1252 NULL,
1253 config_item_table_lookup, items,
1254 true, true, false, info);
1255 if (r < 0)
1256 return log_debug_errno(r, "Failed to parse %s: %m", info->name);
1257
1258 info->type = UNIT_FILE_TYPE_REGULAR;
1259
1260 return
1261 (int) strv_length(info->aliases) +
1262 (int) strv_length(info->wanted_by) +
1263 (int) strv_length(info->required_by);
1264}
1265
1266static int unit_file_load_or_readlink(
1267 InstallContext *c,
1268 UnitFileInstallInfo *info,
1269 const char *path,
1270 const char *root_dir,
1271 SearchFlags flags) {
1272
1273 _cleanup_free_ char *target = NULL;
1274 int r;
1275
1276 r = unit_file_load(c, info, path, flags);
1277 if (r != -ELOOP)
1278 return r;
1279
1280 /* This is a symlink, let's read it. */
1281
1282 r = readlink_malloc(path, &target);
1283 if (r < 0)
1284 return r;
1285
1286 if (path_equal(target, "/dev/null"))
1287 info->type = UNIT_FILE_TYPE_MASKED;
1288 else {
1289 const char *bn;
1290 UnitType a, b;
1291
1292 bn = basename(target);
1293
1294 if (unit_name_is_valid(info->name, UNIT_NAME_PLAIN)) {
1295
1296 if (!unit_name_is_valid(bn, UNIT_NAME_PLAIN))
1297 return -EINVAL;
1298
1299 } else if (unit_name_is_valid(info->name, UNIT_NAME_INSTANCE)) {
1300
1301 if (!unit_name_is_valid(bn, UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE))
1302 return -EINVAL;
1303
1304 } else if (unit_name_is_valid(info->name, UNIT_NAME_TEMPLATE)) {
1305
1306 if (!unit_name_is_valid(bn, UNIT_NAME_TEMPLATE))
1307 return -EINVAL;
1308 } else
1309 return -EINVAL;
1310
1311 /* Enforce that the symlink destination does not
1312 * change the unit file type. */
1313
1314 a = unit_name_to_type(info->name);
1315 b = unit_name_to_type(bn);
1316 if (a < 0 || b < 0 || a != b)
1317 return -EINVAL;
1318
1319 if (path_is_absolute(target))
1320 /* This is an absolute path, prefix the root so that we always deal with fully qualified paths */
1321 info->symlink_target = prefix_root(root_dir, target);
1322 else
1323 /* This is a relative path, take it relative to the dir the symlink is located in. */
1324 info->symlink_target = file_in_same_dir(path, target);
1325 if (!info->symlink_target)
1326 return -ENOMEM;
1327
1328 info->type = UNIT_FILE_TYPE_SYMLINK;
1329 }
1330
1331 return 0;
1332}
1333
1334static int unit_file_search(
1335 InstallContext *c,
1336 UnitFileInstallInfo *info,
1337 const LookupPaths *paths,
1338 SearchFlags flags) {
1339
1340 _cleanup_free_ char *template = NULL;
1341 char **p;
1342 int r;
1343
1344 assert(info);
1345 assert(paths);
1346
1347 /* Was this unit already loaded? */
1348 if (info->type != _UNIT_FILE_TYPE_INVALID)
1349 return 0;
1350
1351 if (info->path)
1352 return unit_file_load_or_readlink(c, info, info->path, paths->root_dir, flags);
1353
1354 assert(info->name);
1355
1356 STRV_FOREACH(p, paths->search_path) {
1357 _cleanup_free_ char *path = NULL;
1358
1359 path = strjoin(*p, "/", info->name);
1360 if (!path)
1361 return -ENOMEM;
1362
1363 r = unit_file_load_or_readlink(c, info, path, paths->root_dir, flags);
1364 if (r >= 0) {
1365 info->path = path;
1366 path = NULL;
1367 return r;
1368 } else if (!IN_SET(r, -ENOENT, -ENOTDIR, -EACCES))
1369 return r;
1370 }
1371
1372 if (unit_name_is_valid(info->name, UNIT_NAME_INSTANCE)) {
1373 /* Unit file doesn't exist, however instance
1374 * enablement was requested. We will check if it is
1375 * possible to load template unit file. */
1376
1377 r = unit_name_template(info->name, &template);
1378 if (r < 0)
1379 return r;
1380
1381 STRV_FOREACH(p, paths->search_path) {
1382 _cleanup_free_ char *path = NULL;
1383
1384 path = strjoin(*p, "/", template);
1385 if (!path)
1386 return -ENOMEM;
1387
1388 r = unit_file_load_or_readlink(c, info, path, paths->root_dir, flags);
1389 if (r >= 0) {
1390 info->path = path;
1391 path = NULL;
1392 return r;
1393 } else if (!IN_SET(r, -ENOENT, -ENOTDIR, -EACCES))
1394 return r;
1395 }
1396 }
1397
1398 log_debug("Cannot find unit %s%s%s.", info->name, template ? " or " : "", strempty(template));
1399 return -ENOENT;
1400}
1401
1402static int install_info_follow(
1403 InstallContext *c,
1404 UnitFileInstallInfo *i,
1405 const char *root_dir,
1406 SearchFlags flags,
1407 bool ignore_different_name) {
1408
1409 assert(c);
1410 assert(i);
1411
1412 if (i->type != UNIT_FILE_TYPE_SYMLINK)
1413 return -EINVAL;
1414 if (!i->symlink_target)
1415 return -EINVAL;
1416
1417 /* If the basename doesn't match, the caller should add a
1418 * complete new entry for this. */
1419
1420 if (!ignore_different_name && !streq(basename(i->symlink_target), i->name))
1421 return -EXDEV;
1422
1423 free_and_replace(i->path, i->symlink_target);
1424 i->type = _UNIT_FILE_TYPE_INVALID;
1425
1426 return unit_file_load_or_readlink(c, i, i->path, root_dir, flags);
1427}
1428
1429/**
1430 * Search for the unit file. If the unit name is a symlink, follow the symlink to the
1431 * target, maybe more than once. Propagate the instance name if present.
1432 */
1433static int install_info_traverse(
1434 UnitFileScope scope,
1435 InstallContext *c,
1436 const LookupPaths *paths,
1437 UnitFileInstallInfo *start,
1438 SearchFlags flags,
1439 UnitFileInstallInfo **ret) {
1440
1441 UnitFileInstallInfo *i;
1442 unsigned k = 0;
1443 int r;
1444
1445 assert(paths);
1446 assert(start);
1447 assert(c);
1448
1449 r = unit_file_search(c, start, paths, flags);
1450 if (r < 0)
1451 return r;
1452
1453 i = start;
1454 while (i->type == UNIT_FILE_TYPE_SYMLINK) {
1455 /* Follow the symlink */
1456
1457 if (++k > UNIT_FILE_FOLLOW_SYMLINK_MAX)
1458 return -ELOOP;
1459
1460 if (!(flags & SEARCH_FOLLOW_CONFIG_SYMLINKS)) {
1461 r = path_is_config(paths, i->path, true);
1462 if (r < 0)
1463 return r;
1464 if (r > 0)
1465 return -ELOOP;
1466 }
1467
1468 r = install_info_follow(c, i, paths->root_dir, flags, false);
1469 if (r == -EXDEV) {
1470 _cleanup_free_ char *buffer = NULL;
1471 const char *bn;
1472
1473 /* Target has a different name, create a new
1474 * install info object for that, and continue
1475 * with that. */
1476
1477 bn = basename(i->symlink_target);
1478
1479 if (unit_name_is_valid(i->name, UNIT_NAME_INSTANCE) &&
1480 unit_name_is_valid(bn, UNIT_NAME_TEMPLATE)) {
1481
1482 _cleanup_free_ char *instance = NULL;
1483
1484 r = unit_name_to_instance(i->name, &instance);
1485 if (r < 0)
1486 return r;
1487
1488 r = unit_name_replace_instance(bn, instance, &buffer);
1489 if (r < 0)
1490 return r;
1491
1492 if (streq(buffer, i->name)) {
1493
1494 /* We filled in the instance, and the target stayed the same? If so, then let's
1495 * honour the link as it is. */
1496
1497 r = install_info_follow(c, i, paths->root_dir, flags, true);
1498 if (r < 0)
1499 return r;
1500
1501 continue;
1502 }
1503
1504 bn = buffer;
1505 }
1506
1507 r = install_info_add(c, bn, NULL, false, &i);
1508 if (r < 0)
1509 return r;
1510
1511 /* Try again, with the new target we found. */
1512 r = unit_file_search(c, i, paths, flags);
1513 if (r == -ENOENT)
1514 /* Translate error code to highlight this specific case */
1515 return -ENOLINK;
1516 }
1517
1518 if (r < 0)
1519 return r;
1520 }
1521
1522 if (ret)
1523 *ret = i;
1524
1525 return 0;
1526}
1527
1528/**
1529 * Call install_info_add() with name_or_path as the path (if name_or_path starts with "/")
1530 * or the name (otherwise). root_dir is prepended to the path.
1531 */
1532static int install_info_add_auto(
1533 InstallContext *c,
1534 const LookupPaths *paths,
1535 const char *name_or_path,
1536 UnitFileInstallInfo **ret) {
1537
1538 assert(c);
1539 assert(name_or_path);
1540
1541 if (path_is_absolute(name_or_path)) {
1542 const char *pp;
1543
1544 pp = prefix_roota(paths->root_dir, name_or_path);
1545
1546 return install_info_add(c, NULL, pp, false, ret);
1547 } else
1548 return install_info_add(c, name_or_path, NULL, false, ret);
1549}
1550
1551static int install_info_discover(
1552 UnitFileScope scope,
1553 InstallContext *c,
1554 const LookupPaths *paths,
1555 const char *name,
1556 SearchFlags flags,
1557 UnitFileInstallInfo **ret,
1558 UnitFileChange **changes,
1559 unsigned *n_changes) {
1560
1561 UnitFileInstallInfo *i;
1562 int r;
1563
1564 assert(c);
1565 assert(paths);
1566 assert(name);
1567
1568 r = install_info_add_auto(c, paths, name, &i);
1569 if (r >= 0)
1570 r = install_info_traverse(scope, c, paths, i, flags, ret);
1571
1572 if (r < 0)
1573 unit_file_changes_add(changes, n_changes, r, name, NULL);
1574 return r;
1575}
1576
1577static int install_info_symlink_alias(
1578 UnitFileInstallInfo *i,
1579 const LookupPaths *paths,
1580 const char *config_path,
1581 bool force,
1582 UnitFileChange **changes,
1583 unsigned *n_changes) {
1584
1585 char **s;
1586 int r = 0, q;
1587
1588 assert(i);
1589 assert(paths);
1590 assert(config_path);
1591
1592 STRV_FOREACH(s, i->aliases) {
1593 _cleanup_free_ char *alias_path = NULL, *dst = NULL;
1594
1595 q = install_full_printf(i, *s, &dst);
1596 if (q < 0)
1597 return q;
1598
1599 alias_path = path_make_absolute(dst, config_path);
1600 if (!alias_path)
1601 return -ENOMEM;
1602
1603 q = create_symlink(paths, i->path, alias_path, force, changes, n_changes);
1604 if (r == 0)
1605 r = q;
1606 }
1607
1608 return r;
1609}
1610
1611static int install_info_symlink_wants(
1612 UnitFileInstallInfo *i,
1613 const LookupPaths *paths,
1614 const char *config_path,
1615 char **list,
1616 const char *suffix,
1617 UnitFileChange **changes,
1618 unsigned *n_changes) {
1619
1620 _cleanup_free_ char *buf = NULL;
1621 const char *n;
1622 char **s;
1623 int r = 0, q;
1624
1625 assert(i);
1626 assert(paths);
1627 assert(config_path);
1628
1629 if (strv_isempty(list))
1630 return 0;
1631
1632 if (unit_name_is_valid(i->name, UNIT_NAME_TEMPLATE) && i->default_instance) {
1633 UnitFileInstallInfo instance = {
1634 .type = _UNIT_FILE_TYPE_INVALID,
1635 };
1636 _cleanup_free_ char *path = NULL;
1637
1638 r = unit_name_replace_instance(i->name, i->default_instance, &buf);
1639 if (r < 0)
1640 return r;
1641
1642 instance.name = buf;
1643 r = unit_file_search(NULL, &instance, paths, SEARCH_FOLLOW_CONFIG_SYMLINKS);
1644 if (r < 0)
1645 return r;
1646
1647 path = instance.path;
1648 instance.path = NULL;
1649
1650 if (instance.type == UNIT_FILE_TYPE_MASKED) {
1651 unit_file_changes_add(changes, n_changes, -ERFKILL, path, NULL);
1652 return -ERFKILL;
1653 }
1654
1655 n = buf;
1656 } else
1657 n = i->name;
1658
1659 STRV_FOREACH(s, list) {
1660 _cleanup_free_ char *path = NULL, *dst = NULL;
1661
1662 q = install_full_printf(i, *s, &dst);
1663 if (q < 0)
1664 return q;
1665
1666 if (!unit_name_is_valid(dst, UNIT_NAME_ANY)) {
1667 r = -EINVAL;
1668 continue;
1669 }
1670
1671 path = strjoin(config_path, "/", dst, suffix, n);
1672 if (!path)
1673 return -ENOMEM;
1674
1675 q = create_symlink(paths, i->path, path, true, changes, n_changes);
1676 if (r == 0)
1677 r = q;
1678 }
1679
1680 return r;
1681}
1682
1683static int install_info_symlink_link(
1684 UnitFileInstallInfo *i,
1685 const LookupPaths *paths,
1686 const char *config_path,
1687 bool force,
1688 UnitFileChange **changes,
1689 unsigned *n_changes) {
1690
1691 _cleanup_free_ char *path = NULL;
1692 int r;
1693
1694 assert(i);
1695 assert(paths);
1696 assert(config_path);
1697 assert(i->path);
1698
1699 r = in_search_path(paths, i->path);
1700 if (r < 0)
1701 return r;
1702 if (r > 0)
1703 return 0;
1704
1705 path = strjoin(config_path, "/", i->name);
1706 if (!path)
1707 return -ENOMEM;
1708
1709 return create_symlink(paths, i->path, path, force, changes, n_changes);
1710}
1711
1712static int install_info_apply(
1713 UnitFileInstallInfo *i,
1714 const LookupPaths *paths,
1715 const char *config_path,
1716 bool force,
1717 UnitFileChange **changes,
1718 unsigned *n_changes) {
1719
1720 int r, q;
1721
1722 assert(i);
1723 assert(paths);
1724 assert(config_path);
1725
1726 if (i->type != UNIT_FILE_TYPE_REGULAR)
1727 return 0;
1728
1729 r = install_info_symlink_alias(i, paths, config_path, force, changes, n_changes);
1730
1731 q = install_info_symlink_wants(i, paths, config_path, i->wanted_by, ".wants/", changes, n_changes);
1732 if (r == 0)
1733 r = q;
1734
1735 q = install_info_symlink_wants(i, paths, config_path, i->required_by, ".requires/", changes, n_changes);
1736 if (r == 0)
1737 r = q;
1738
1739 q = install_info_symlink_link(i, paths, config_path, force, changes, n_changes);
1740 /* Do not count links to the unit file towards the "carries_install_info" count */
1741 if (r == 0 && q < 0)
1742 r = q;
1743
1744 return r;
1745}
1746
1747static int install_context_apply(
1748 UnitFileScope scope,
1749 InstallContext *c,
1750 const LookupPaths *paths,
1751 const char *config_path,
1752 bool force,
1753 SearchFlags flags,
1754 UnitFileChange **changes,
1755 unsigned *n_changes) {
1756
1757 UnitFileInstallInfo *i;
1758 int r;
1759
1760 assert(c);
1761 assert(paths);
1762 assert(config_path);
1763
1764 if (ordered_hashmap_isempty(c->will_process))
1765 return 0;
1766
1767 r = ordered_hashmap_ensure_allocated(&c->have_processed, &string_hash_ops);
1768 if (r < 0)
1769 return r;
1770
1771 r = 0;
1772 while ((i = ordered_hashmap_first(c->will_process))) {
1773 int q;
1774
1775 q = ordered_hashmap_move_one(c->have_processed, c->will_process, i->name);
1776 if (q < 0)
1777 return q;
1778
1779 r = install_info_traverse(scope, c, paths, i, flags, NULL);
1780 if (r < 0) {
1781 unit_file_changes_add(changes, n_changes, r, i->name, NULL);
1782 return r;
1783 }
1784
1785 /* We can attempt to process a masked unit when a different unit
1786 * that we were processing specifies it in Also=. */
1787 if (i->type == UNIT_FILE_TYPE_MASKED) {
1788 unit_file_changes_add(changes, n_changes, UNIT_FILE_IS_MASKED, i->path, NULL);
1789 if (r >= 0)
1790 /* Assume that something *could* have been enabled here,
1791 * avoid "empty [Install] section" warning. */
1792 r += 1;
1793 continue;
1794 }
1795
1796 if (i->type != UNIT_FILE_TYPE_REGULAR)
1797 continue;
1798
1799 q = install_info_apply(i, paths, config_path, force, changes, n_changes);
1800 if (r >= 0) {
1801 if (q < 0)
1802 r = q;
1803 else
1804 r += q;
1805 }
1806 }
1807
1808 return r;
1809}
1810
1811static int install_context_mark_for_removal(
1812 UnitFileScope scope,
1813 InstallContext *c,
1814 const LookupPaths *paths,
1815 Set **remove_symlinks_to,
1816 const char *config_path,
1817 UnitFileChange **changes,
1818 unsigned *n_changes) {
1819
1820 UnitFileInstallInfo *i;
1821 int r;
1822
1823 assert(c);
1824 assert(paths);
1825 assert(config_path);
1826
1827 /* Marks all items for removal */
1828
1829 if (ordered_hashmap_isempty(c->will_process))
1830 return 0;
1831
1832 r = ordered_hashmap_ensure_allocated(&c->have_processed, &string_hash_ops);
1833 if (r < 0)
1834 return r;
1835
1836 while ((i = ordered_hashmap_first(c->will_process))) {
1837
1838 r = ordered_hashmap_move_one(c->have_processed, c->will_process, i->name);
1839 if (r < 0)
1840 return r;
1841
1842 r = install_info_traverse(scope, c, paths, i, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, NULL);
1843 if (r == -ENOLINK) {
1844 log_debug_errno(r, "Name %s leads to a dangling symlink, removing name.", i->name);
1845 unit_file_changes_add(changes, n_changes, UNIT_FILE_IS_DANGLING, i->path ?: i->name, NULL);
1846 } else if (r == -ENOENT) {
1847
1848 if (i->auxiliary) /* some unit specified in Also= or similar is missing */
1849 log_debug_errno(r, "Auxiliary unit of %s not found, removing name.", i->name);
1850 else {
1851 log_debug_errno(r, "Unit %s not found, removing name.", i->name);
1852 unit_file_changes_add(changes, n_changes, r, i->path ?: i->name, NULL);
1853 }
1854
1855 } else if (r < 0) {
1856 log_debug_errno(r, "Failed to find unit %s, removing name: %m", i->name);
1857 unit_file_changes_add(changes, n_changes, r, i->path ?: i->name, NULL);
1858 } else if (i->type == UNIT_FILE_TYPE_MASKED) {
1859 log_debug("Unit file %s is masked, ignoring.", i->name);
1860 unit_file_changes_add(changes, n_changes, UNIT_FILE_IS_MASKED, i->path ?: i->name, NULL);
1861 continue;
1862 } else if (i->type != UNIT_FILE_TYPE_REGULAR) {
1863 log_debug("Unit %s has type %s, ignoring.", i->name, unit_file_type_to_string(i->type) ?: "invalid");
1864 continue;
1865 }
1866
1867 r = mark_symlink_for_removal(remove_symlinks_to, i->name);
1868 if (r < 0)
1869 return r;
1870 }
1871
1872 return 0;
1873}
1874
1875int unit_file_mask(
1876 UnitFileScope scope,
1877 UnitFileFlags flags,
1878 const char *root_dir,
1879 char **files,
1880 UnitFileChange **changes,
1881 unsigned *n_changes) {
1882
1883 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1884 const char *config_path;
1885 char **i;
1886 int r;
1887
1888 assert(scope >= 0);
1889 assert(scope < _UNIT_FILE_SCOPE_MAX);
1890
1891 r = lookup_paths_init(&paths, scope, 0, root_dir);
1892 if (r < 0)
1893 return r;
1894
1895 config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
1896 if (!config_path)
1897 return -ENXIO;
1898
1899 STRV_FOREACH(i, files) {
1900 _cleanup_free_ char *path = NULL;
1901 int q;
1902
1903 if (!unit_name_is_valid(*i, UNIT_NAME_ANY)) {
1904 if (r == 0)
1905 r = -EINVAL;
1906 continue;
1907 }
1908
1909 path = path_make_absolute(*i, config_path);
1910 if (!path)
1911 return -ENOMEM;
1912
1913 q = create_symlink(&paths, "/dev/null", path, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
1914 if (q < 0 && r >= 0)
1915 r = q;
1916 }
1917
1918 return r;
1919}
1920
1921int unit_file_unmask(
1922 UnitFileScope scope,
1923 UnitFileFlags flags,
1924 const char *root_dir,
1925 char **files,
1926 UnitFileChange **changes,
1927 unsigned *n_changes) {
1928
1929 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1930 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
1931 _cleanup_strv_free_ char **todo = NULL;
1932 size_t n_todo = 0, n_allocated = 0;
1933 const char *config_path;
1934 char **i;
1935 bool dry_run;
1936 int r, q;
1937
1938 assert(scope >= 0);
1939 assert(scope < _UNIT_FILE_SCOPE_MAX);
1940
1941 r = lookup_paths_init(&paths, scope, 0, root_dir);
1942 if (r < 0)
1943 return r;
1944
1945 config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
1946 if (!config_path)
1947 return -ENXIO;
1948
1949 dry_run = !!(flags & UNIT_FILE_DRY_RUN);
1950
1951 STRV_FOREACH(i, files) {
1952 _cleanup_free_ char *path = NULL;
1953
1954 if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
1955 return -EINVAL;
1956
1957 path = path_make_absolute(*i, config_path);
1958 if (!path)
1959 return -ENOMEM;
1960
1961 r = null_or_empty_path(path);
1962 if (r == -ENOENT)
1963 continue;
1964 if (r < 0)
1965 return r;
1966 if (r == 0)
1967 continue;
1968
1969 if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
1970 return -ENOMEM;
1971
1972 todo[n_todo] = strdup(*i);
1973 if (!todo[n_todo])
1974 return -ENOMEM;
1975
1976 n_todo++;
1977 }
1978
1979 strv_uniq(todo);
1980
1981 r = 0;
1982 STRV_FOREACH(i, todo) {
1983 _cleanup_free_ char *path = NULL;
1984 const char *rp;
1985
1986 path = path_make_absolute(*i, config_path);
1987 if (!path)
1988 return -ENOMEM;
1989
1990 if (!dry_run && unlink(path) < 0) {
1991 if (errno != ENOENT) {
1992 if (r >= 0)
1993 r = -errno;
1994 unit_file_changes_add(changes, n_changes, -errno, path, NULL);
1995 }
1996
1997 continue;
1998 }
1999
2000 unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
2001
2002 rp = skip_root(&paths, path);
2003 q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: path);
2004 if (q < 0)
2005 return q;
2006 }
2007
2008 q = remove_marked_symlinks(remove_symlinks_to, config_path, &paths, dry_run, changes, n_changes);
2009 if (r >= 0)
2010 r = q;
2011
2012 return r;
2013}
2014
2015int unit_file_link(
2016 UnitFileScope scope,
2017 UnitFileFlags flags,
2018 const char *root_dir,
2019 char **files,
2020 UnitFileChange **changes,
2021 unsigned *n_changes) {
2022
2023 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2024 _cleanup_strv_free_ char **todo = NULL;
2025 size_t n_todo = 0, n_allocated = 0;
2026 const char *config_path;
2027 char **i;
2028 int r, q;
2029
2030 assert(scope >= 0);
2031 assert(scope < _UNIT_FILE_SCOPE_MAX);
2032
2033 r = lookup_paths_init(&paths, scope, 0, root_dir);
2034 if (r < 0)
2035 return r;
2036
2037 config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
2038 if (!config_path)
2039 return -ENXIO;
2040
2041 STRV_FOREACH(i, files) {
2042 _cleanup_free_ char *full = NULL;
2043 struct stat st;
2044 char *fn;
2045
2046 if (!path_is_absolute(*i))
2047 return -EINVAL;
2048
2049 fn = basename(*i);
2050 if (!unit_name_is_valid(fn, UNIT_NAME_ANY))
2051 return -EINVAL;
2052
2053 full = prefix_root(paths.root_dir, *i);
2054 if (!full)
2055 return -ENOMEM;
2056
2057 if (lstat(full, &st) < 0)
2058 return -errno;
2059 if (S_ISLNK(st.st_mode))
2060 return -ELOOP;
2061 if (S_ISDIR(st.st_mode))
2062 return -EISDIR;
2063 if (!S_ISREG(st.st_mode))
2064 return -ENOTTY;
2065
2066 q = in_search_path(&paths, *i);
2067 if (q < 0)
2068 return q;
2069 if (q > 0)
2070 continue;
2071
2072 if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
2073 return -ENOMEM;
2074
2075 todo[n_todo] = strdup(*i);
2076 if (!todo[n_todo])
2077 return -ENOMEM;
2078
2079 n_todo++;
2080 }
2081
2082 strv_uniq(todo);
2083
2084 r = 0;
2085 STRV_FOREACH(i, todo) {
2086 _cleanup_free_ char *new_path = NULL;
2087
2088 new_path = path_make_absolute(basename(*i), config_path);
2089 if (!new_path)
2090 return -ENOMEM;
2091
2092 q = create_symlink(&paths, *i, new_path, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
2093 if (q < 0 && r >= 0)
2094 r = q;
2095 }
2096
2097 return r;
2098}
2099
2100static int path_shall_revert(const LookupPaths *paths, const char *path) {
2101 int r;
2102
2103 assert(paths);
2104 assert(path);
2105
2106 /* Checks whether the path is one where the drop-in directories shall be removed. */
2107
2108 r = path_is_config(paths, path, true);
2109 if (r != 0)
2110 return r;
2111
2112 r = path_is_control(paths, path);
2113 if (r != 0)
2114 return r;
2115
2116 return path_is_transient(paths, path);
2117}
2118
2119int unit_file_revert(
2120 UnitFileScope scope,
2121 const char *root_dir,
2122 char **files,
2123 UnitFileChange **changes,
2124 unsigned *n_changes) {
2125
2126 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
2127 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2128 _cleanup_strv_free_ char **todo = NULL;
2129 size_t n_todo = 0, n_allocated = 0;
2130 char **i;
2131 int r, q;
2132
2133 /* Puts a unit file back into vendor state. This means:
2134 *
2135 * a) we remove all drop-in snippets added by the user ("config"), add to transient units ("transient"), and
2136 * added via "systemctl set-property" ("control"), but not if the drop-in is generated ("generated").
2137 *
2138 * c) if there's a vendor unit file (i.e. one in /usr) we remove any configured overriding unit files (i.e. in
2139 * "config", but not in "transient" or "control" or even "generated").
2140 *
2141 * We remove all that in both the runtime and the persistent directories, if that applies.
2142 */
2143
2144 r = lookup_paths_init(&paths, scope, 0, root_dir);
2145 if (r < 0)
2146 return r;
2147
2148 STRV_FOREACH(i, files) {
2149 bool has_vendor = false;
2150 char **p;
2151
2152 if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
2153 return -EINVAL;
2154
2155 STRV_FOREACH(p, paths.search_path) {
2156 _cleanup_free_ char *path = NULL, *dropin = NULL;
2157 struct stat st;
2158
2159 path = path_make_absolute(*i, *p);
2160 if (!path)
2161 return -ENOMEM;
2162
2163 r = lstat(path, &st);
2164 if (r < 0) {
2165 if (errno != ENOENT)
2166 return -errno;
2167 } else if (S_ISREG(st.st_mode)) {
2168 /* Check if there's a vendor version */
2169 r = path_is_vendor(&paths, path);
2170 if (r < 0)
2171 return r;
2172 if (r > 0)
2173 has_vendor = true;
2174 }
2175
2176 dropin = strappend(path, ".d");
2177 if (!dropin)
2178 return -ENOMEM;
2179
2180 r = lstat(dropin, &st);
2181 if (r < 0) {
2182 if (errno != ENOENT)
2183 return -errno;
2184 } else if (S_ISDIR(st.st_mode)) {
2185 /* Remove the drop-ins */
2186 r = path_shall_revert(&paths, dropin);
2187 if (r < 0)
2188 return r;
2189 if (r > 0) {
2190 if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
2191 return -ENOMEM;
2192
2193 todo[n_todo++] = dropin;
2194 dropin = NULL;
2195 }
2196 }
2197 }
2198
2199 if (!has_vendor)
2200 continue;
2201
2202 /* OK, there's a vendor version, hence drop all configuration versions */
2203 STRV_FOREACH(p, paths.search_path) {
2204 _cleanup_free_ char *path = NULL;
2205 struct stat st;
2206
2207 path = path_make_absolute(*i, *p);
2208 if (!path)
2209 return -ENOMEM;
2210
2211 r = lstat(path, &st);
2212 if (r < 0) {
2213 if (errno != ENOENT)
2214 return -errno;
2215 } else if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
2216 r = path_is_config(&paths, path, true);
2217 if (r < 0)
2218 return r;
2219 if (r > 0) {
2220 if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
2221 return -ENOMEM;
2222
2223 todo[n_todo++] = path;
2224 path = NULL;
2225 }
2226 }
2227 }
2228 }
2229
2230 strv_uniq(todo);
2231
2232 r = 0;
2233 STRV_FOREACH(i, todo) {
2234 _cleanup_strv_free_ char **fs = NULL;
2235 const char *rp;
2236 char **j;
2237
2238 (void) get_files_in_directory(*i, &fs);
2239
2240 q = rm_rf(*i, REMOVE_ROOT|REMOVE_PHYSICAL);
2241 if (q < 0 && q != -ENOENT && r >= 0) {
2242 r = q;
2243 continue;
2244 }
2245
2246 STRV_FOREACH(j, fs) {
2247 _cleanup_free_ char *t = NULL;
2248
2249 t = strjoin(*i, "/", *j);
2250 if (!t)
2251 return -ENOMEM;
2252
2253 unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, t, NULL);
2254 }
2255
2256 unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, *i, NULL);
2257
2258 rp = skip_root(&paths, *i);
2259 q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: *i);
2260 if (q < 0)
2261 return q;
2262 }
2263
2264 q = remove_marked_symlinks(remove_symlinks_to, paths.runtime_config, &paths, false, changes, n_changes);
2265 if (r >= 0)
2266 r = q;
2267
2268 q = remove_marked_symlinks(remove_symlinks_to, paths.persistent_config, &paths, false, changes, n_changes);
2269 if (r >= 0)
2270 r = q;
2271
2272 return r;
2273}
2274
2275int unit_file_add_dependency(
2276 UnitFileScope scope,
2277 UnitFileFlags flags,
2278 const char *root_dir,
2279 char **files,
2280 const char *target,
2281 UnitDependency dep,
2282 UnitFileChange **changes,
2283 unsigned *n_changes) {
2284
2285 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2286 _cleanup_(install_context_done) InstallContext c = {};
2287 UnitFileInstallInfo *i, *target_info;
2288 const char *config_path;
2289 char **f;
2290 int r;
2291
2292 assert(scope >= 0);
2293 assert(scope < _UNIT_FILE_SCOPE_MAX);
2294 assert(target);
2295
2296 if (!IN_SET(dep, UNIT_WANTS, UNIT_REQUIRES))
2297 return -EINVAL;
2298
2299 if (!unit_name_is_valid(target, UNIT_NAME_ANY))
2300 return -EINVAL;
2301
2302 r = lookup_paths_init(&paths, scope, 0, root_dir);
2303 if (r < 0)
2304 return r;
2305
2306 config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
2307 if (!config_path)
2308 return -ENXIO;
2309
2310 r = install_info_discover(scope, &c, &paths, target, SEARCH_FOLLOW_CONFIG_SYMLINKS,
2311 &target_info, changes, n_changes);
2312 if (r < 0)
2313 return r;
2314 r = install_info_may_process(target_info, &paths, changes, n_changes);
2315 if (r < 0)
2316 return r;
2317
2318 assert(target_info->type == UNIT_FILE_TYPE_REGULAR);
2319
2320 STRV_FOREACH(f, files) {
2321 char ***l;
2322
2323 r = install_info_discover(scope, &c, &paths, *f, SEARCH_FOLLOW_CONFIG_SYMLINKS,
2324 &i, changes, n_changes);
2325 if (r < 0)
2326 return r;
2327 r = install_info_may_process(i, &paths, changes, n_changes);
2328 if (r < 0)
2329 return r;
2330
2331 assert(i->type == UNIT_FILE_TYPE_REGULAR);
2332
2333 /* We didn't actually load anything from the unit
2334 * file, but instead just add in our new symlink to
2335 * create. */
2336
2337 if (dep == UNIT_WANTS)
2338 l = &i->wanted_by;
2339 else
2340 l = &i->required_by;
2341
2342 strv_free(*l);
2343 *l = strv_new(target_info->name, NULL);
2344 if (!*l)
2345 return -ENOMEM;
2346 }
2347
2348 return install_context_apply(scope, &c, &paths, config_path, !!(flags & UNIT_FILE_FORCE), SEARCH_FOLLOW_CONFIG_SYMLINKS, changes, n_changes);
2349}
2350
2351int unit_file_enable(
2352 UnitFileScope scope,
2353 UnitFileFlags flags,
2354 const char *root_dir,
2355 char **files,
2356 UnitFileChange **changes,
2357 unsigned *n_changes) {
2358
2359 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2360 _cleanup_(install_context_done) InstallContext c = {};
2361 const char *config_path;
2362 UnitFileInstallInfo *i;
2363 char **f;
2364 int r;
2365
2366 assert(scope >= 0);
2367 assert(scope < _UNIT_FILE_SCOPE_MAX);
2368
2369 r = lookup_paths_init(&paths, scope, 0, root_dir);
2370 if (r < 0)
2371 return r;
2372
2373 config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
2374 if (!config_path)
2375 return -ENXIO;
2376
2377 STRV_FOREACH(f, files) {
2378 r = install_info_discover(scope, &c, &paths, *f, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS,
2379 &i, changes, n_changes);
2380 if (r < 0)
2381 return r;
2382 r = install_info_may_process(i, &paths, changes, n_changes);
2383 if (r < 0)
2384 return r;
2385
2386 assert(i->type == UNIT_FILE_TYPE_REGULAR);
2387 }
2388
2389 /* This will return the number of symlink rules that were
2390 supposed to be created, not the ones actually created. This
2391 is useful to determine whether the passed files had any
2392 installation data at all. */
2393
2394 return install_context_apply(scope, &c, &paths, config_path, !!(flags & UNIT_FILE_FORCE), SEARCH_LOAD, changes, n_changes);
2395}
2396
2397int unit_file_disable(
2398 UnitFileScope scope,
2399 UnitFileFlags flags,
2400 const char *root_dir,
2401 char **files,
2402 UnitFileChange **changes,
2403 unsigned *n_changes) {
2404
2405 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2406 _cleanup_(install_context_done) InstallContext c = {};
2407 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
2408 const char *config_path;
2409 char **i;
2410 int r;
2411
2412 assert(scope >= 0);
2413 assert(scope < _UNIT_FILE_SCOPE_MAX);
2414
2415 r = lookup_paths_init(&paths, scope, 0, root_dir);
2416 if (r < 0)
2417 return r;
2418
2419 config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
2420 if (!config_path)
2421 return -ENXIO;
2422
2423 STRV_FOREACH(i, files) {
2424 if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
2425 return -EINVAL;
2426
2427 r = install_info_add(&c, *i, NULL, false, NULL);
2428 if (r < 0)
2429 return r;
2430 }
2431
2432 r = install_context_mark_for_removal(scope, &c, &paths, &remove_symlinks_to, config_path, changes, n_changes);
2433 if (r < 0)
2434 return r;
2435
2436 return remove_marked_symlinks(remove_symlinks_to, config_path, &paths, !!(flags & UNIT_FILE_DRY_RUN), changes, n_changes);
2437}
2438
2439int unit_file_reenable(
2440 UnitFileScope scope,
2441 UnitFileFlags flags,
2442 const char *root_dir,
2443 char **files,
2444 UnitFileChange **changes,
2445 unsigned *n_changes) {
2446
2447 char **n;
2448 int r;
2449 size_t l, i;
2450
2451 /* First, we invoke the disable command with only the basename... */
2452 l = strv_length(files);
2453 n = newa(char*, l+1);
2454 for (i = 0; i < l; i++)
2455 n[i] = basename(files[i]);
2456 n[i] = NULL;
2457
2458 r = unit_file_disable(scope, flags, root_dir, n, changes, n_changes);
2459 if (r < 0)
2460 return r;
2461
2462 /* But the enable command with the full name */
2463 return unit_file_enable(scope, flags, root_dir, files, changes, n_changes);
2464}
2465
2466int unit_file_set_default(
2467 UnitFileScope scope,
2468 UnitFileFlags flags,
2469 const char *root_dir,
2470 const char *name,
2471 UnitFileChange **changes,
2472 unsigned *n_changes) {
2473
2474 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2475 _cleanup_(install_context_done) InstallContext c = {};
2476 UnitFileInstallInfo *i;
2477 const char *new_path;
2478 int r;
2479
2480 assert(scope >= 0);
2481 assert(scope < _UNIT_FILE_SCOPE_MAX);
2482 assert(name);
2483
2484 if (unit_name_to_type(name) != UNIT_TARGET) /* this also validates the name */
2485 return -EINVAL;
2486 if (streq(name, SPECIAL_DEFAULT_TARGET))
2487 return -EINVAL;
2488
2489 r = lookup_paths_init(&paths, scope, 0, root_dir);
2490 if (r < 0)
2491 return r;
2492
2493 r = install_info_discover(scope, &c, &paths, name, 0, &i, changes, n_changes);
2494 if (r < 0)
2495 return r;
2496 r = install_info_may_process(i, &paths, changes, n_changes);
2497 if (r < 0)
2498 return r;
2499
2500 new_path = strjoina(paths.persistent_config, "/" SPECIAL_DEFAULT_TARGET);
2501 return create_symlink(&paths, i->path, new_path, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
2502}
2503
2504int unit_file_get_default(
2505 UnitFileScope scope,
2506 const char *root_dir,
2507 char **name) {
2508
2509 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2510 _cleanup_(install_context_done) InstallContext c = {};
2511 UnitFileInstallInfo *i;
2512 char *n;
2513 int r;
2514
2515 assert(scope >= 0);
2516 assert(scope < _UNIT_FILE_SCOPE_MAX);
2517 assert(name);
2518
2519 r = lookup_paths_init(&paths, scope, 0, root_dir);
2520 if (r < 0)
2521 return r;
2522
2523 r = install_info_discover(scope, &c, &paths, SPECIAL_DEFAULT_TARGET, SEARCH_FOLLOW_CONFIG_SYMLINKS,
2524 &i, NULL, NULL);
2525 if (r < 0)
2526 return r;
2527 r = install_info_may_process(i, &paths, NULL, 0);
2528 if (r < 0)
2529 return r;
2530
2531 n = strdup(i->name);
2532 if (!n)
2533 return -ENOMEM;
2534
2535 *name = n;
2536 return 0;
2537}
2538
2539static int unit_file_lookup_state(
2540 UnitFileScope scope,
2541 const LookupPaths *paths,
2542 const char *name,
2543 UnitFileState *ret) {
2544
2545 _cleanup_(install_context_done) InstallContext c = {};
2546 UnitFileInstallInfo *i;
2547 UnitFileState state;
2548 int r;
2549
2550 assert(paths);
2551 assert(name);
2552
2553 if (!unit_name_is_valid(name, UNIT_NAME_ANY))
2554 return -EINVAL;
2555
2556 r = install_info_discover(scope, &c, paths, name, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS,
2557 &i, NULL, NULL);
2558 if (r < 0)
2559 return r;
2560
2561 /* Shortcut things, if the caller just wants to know if this unit exists. */
2562 if (!ret)
2563 return 0;
2564
2565 switch (i->type) {
2566
2567 case UNIT_FILE_TYPE_MASKED:
2568 r = path_is_runtime(paths, i->path, true);
2569 if (r < 0)
2570 return r;
2571
2572 state = r > 0 ? UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
2573 break;
2574
2575 case UNIT_FILE_TYPE_REGULAR:
2576 r = path_is_generator(paths, i->path);
2577 if (r < 0)
2578 return r;
2579 if (r > 0) {
2580 state = UNIT_FILE_GENERATED;
2581 break;
2582 }
2583
2584 r = path_is_transient(paths, i->path);
2585 if (r < 0)
2586 return r;
2587 if (r > 0) {
2588 state = UNIT_FILE_TRANSIENT;
2589 break;
2590 }
2591
2592 r = find_symlinks_in_scope(paths, i->name, &state);
2593 if (r < 0)
2594 return r;
2595 if (r == 0) {
2596 if (UNIT_FILE_INSTALL_INFO_HAS_RULES(i))
2597 state = UNIT_FILE_DISABLED;
2598 else if (UNIT_FILE_INSTALL_INFO_HAS_ALSO(i))
2599 state = UNIT_FILE_INDIRECT;
2600 else
2601 state = UNIT_FILE_STATIC;
2602 }
2603
2604 break;
2605
2606 default:
2607 assert_not_reached("Unexpect unit file type.");
2608 }
2609
2610 *ret = state;
2611 return 0;
2612}
2613
2614int unit_file_get_state(
2615 UnitFileScope scope,
2616 const char *root_dir,
2617 const char *name,
2618 UnitFileState *ret) {
2619
2620 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2621 int r;
2622
2623 assert(scope >= 0);
2624 assert(scope < _UNIT_FILE_SCOPE_MAX);
2625 assert(name);
2626
2627 r = lookup_paths_init(&paths, scope, 0, root_dir);
2628 if (r < 0)
2629 return r;
2630
2631 return unit_file_lookup_state(scope, &paths, name, ret);
2632}
2633
2634int unit_file_exists(UnitFileScope scope, const LookupPaths *paths, const char *name) {
2635 _cleanup_(install_context_done) InstallContext c = {};
2636 int r;
2637
2638 assert(paths);
2639 assert(name);
2640
2641 if (!unit_name_is_valid(name, UNIT_NAME_ANY))
2642 return -EINVAL;
2643
2644 r = install_info_discover(scope, &c, paths, name, 0, NULL, NULL, NULL);
2645 if (r == -ENOENT)
2646 return 0;
2647 if (r < 0)
2648 return r;
2649
2650 return 1;
2651}
2652
2653static int read_presets(UnitFileScope scope, const char *root_dir, Presets *presets) {
2654 _cleanup_(presets_freep) Presets ps = {};
2655 size_t n_allocated = 0;
2656 _cleanup_strv_free_ char **files = NULL;
2657 char **p;
2658 int r;
2659
2660 assert(scope >= 0);
2661 assert(scope < _UNIT_FILE_SCOPE_MAX);
2662 assert(presets);
2663
2664 if (scope == UNIT_FILE_SYSTEM)
2665 r = conf_files_list(&files, ".preset", root_dir, 0,
2666 "/etc/systemd/system-preset",
2667 "/usr/local/lib/systemd/system-preset",
2668 "/usr/lib/systemd/system-preset",
2669#ifdef HAVE_SPLIT_USR
2670 "/lib/systemd/system-preset",
2671#endif
2672 NULL);
2673 else if (scope == UNIT_FILE_GLOBAL)
2674 r = conf_files_list(&files, ".preset", root_dir, 0,
2675 "/etc/systemd/user-preset",
2676 "/usr/local/lib/systemd/user-preset",
2677 "/usr/lib/systemd/user-preset",
2678 NULL);
2679 else {
2680 *presets = (Presets){};
2681
2682 return 0;
2683 }
2684
2685 if (r < 0)
2686 return r;
2687
2688 STRV_FOREACH(p, files) {
2689 _cleanup_fclose_ FILE *f;
2690 char line[LINE_MAX];
2691 int n = 0;
2692
2693 f = fopen(*p, "re");
2694 if (!f) {
2695 if (errno == ENOENT)
2696 continue;
2697
2698 return -errno;
2699 }
2700
2701 FOREACH_LINE(line, f, return -errno) {
2702 PresetRule rule = {};
2703 const char *parameter;
2704 char *l;
2705
2706 l = strstrip(line);
2707 n++;
2708
2709 if (isempty(l))
2710 continue;
2711 if (strchr(COMMENTS, *l))
2712 continue;
2713
2714 parameter = first_word(l, "enable");
2715 if (parameter) {
2716 char *pattern;
2717
2718 pattern = strdup(parameter);
2719 if (!pattern)
2720 return -ENOMEM;
2721
2722 rule = (PresetRule) {
2723 .pattern = pattern,
2724 .action = PRESET_ENABLE,
2725 };
2726 }
2727
2728 parameter = first_word(l, "disable");
2729 if (parameter) {
2730 char *pattern;
2731
2732 pattern = strdup(parameter);
2733 if (!pattern)
2734 return -ENOMEM;
2735
2736 rule = (PresetRule) {
2737 .pattern = pattern,
2738 .action = PRESET_DISABLE,
2739 };
2740 }
2741
2742 if (rule.action) {
2743 if (!GREEDY_REALLOC(ps.rules, n_allocated, ps.n_rules + 1))
2744 return -ENOMEM;
2745
2746 ps.rules[ps.n_rules++] = rule;
2747 continue;
2748 }
2749
2750 log_syntax(NULL, LOG_WARNING, *p, n, 0, "Couldn't parse line '%s'. Ignoring.", line);
2751 }
2752 }
2753
2754 *presets = ps;
2755 ps = (Presets){};
2756
2757 return 0;
2758}
2759
2760static int query_presets(const char *name, const Presets presets) {
2761 PresetAction action = PRESET_UNKNOWN;
2762 size_t i;
2763
2764 if (!unit_name_is_valid(name, UNIT_NAME_ANY))
2765 return -EINVAL;
2766
2767 for (i = 0; i < presets.n_rules; i++)
2768 if (fnmatch(presets.rules[i].pattern, name, FNM_NOESCAPE) == 0) {
2769 action = presets.rules[i].action;
2770 break;
2771 }
2772
2773 switch (action) {
2774 case PRESET_UNKNOWN:
2775 log_debug("Preset files don't specify rule for %s. Enabling.", name);
2776 return 1;
2777 case PRESET_ENABLE:
2778 log_debug("Preset files say enable %s.", name);
2779 return 1;
2780 case PRESET_DISABLE:
2781 log_debug("Preset files say disable %s.", name);
2782 return 0;
2783 default:
2784 assert_not_reached("invalid preset action");
2785 }
2786}
2787
2788int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name) {
2789 _cleanup_(presets_freep) Presets presets = {};
2790 int r;
2791
2792 r = read_presets(scope, root_dir, &presets);
2793 if (r < 0)
2794 return r;
2795
2796 return query_presets(name, presets);
2797}
2798
2799static int execute_preset(
2800 UnitFileScope scope,
2801 InstallContext *plus,
2802 InstallContext *minus,
2803 const LookupPaths *paths,
2804 const char *config_path,
2805 char **files,
2806 UnitFilePresetMode mode,
2807 bool force,
2808 UnitFileChange **changes,
2809 unsigned *n_changes) {
2810
2811 int r;
2812
2813 assert(plus);
2814 assert(minus);
2815 assert(paths);
2816 assert(config_path);
2817
2818 if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
2819 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
2820
2821 r = install_context_mark_for_removal(scope, minus, paths, &remove_symlinks_to, config_path, changes, n_changes);
2822 if (r < 0)
2823 return r;
2824
2825 r = remove_marked_symlinks(remove_symlinks_to, config_path, paths, false, changes, n_changes);
2826 } else
2827 r = 0;
2828
2829 if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
2830 int q;
2831
2832 /* Returns number of symlinks that where supposed to be installed. */
2833 q = install_context_apply(scope, plus, paths, config_path, force, SEARCH_LOAD, changes, n_changes);
2834 if (r >= 0) {
2835 if (q < 0)
2836 r = q;
2837 else
2838 r += q;
2839 }
2840 }
2841
2842 return r;
2843}
2844
2845static int preset_prepare_one(
2846 UnitFileScope scope,
2847 InstallContext *plus,
2848 InstallContext *minus,
2849 LookupPaths *paths,
2850 const char *name,
2851 Presets presets,
2852 UnitFileChange **changes,
2853 unsigned *n_changes) {
2854
2855 _cleanup_(install_context_done) InstallContext tmp = {};
2856 UnitFileInstallInfo *i;
2857 int r;
2858
2859 if (install_info_find(plus, name) || install_info_find(minus, name))
2860 return 0;
2861
2862 r = install_info_discover(scope, &tmp, paths, name, SEARCH_FOLLOW_CONFIG_SYMLINKS,
2863 &i, changes, n_changes);
2864 if (r < 0)
2865 return r;
2866 if (!streq(name, i->name)) {
2867 log_debug("Skipping %s because is an alias for %s", name, i->name);
2868 return 0;
2869 }
2870
2871 r = query_presets(name, presets);
2872 if (r < 0)
2873 return r;
2874
2875 if (r > 0) {
2876 r = install_info_discover(scope, plus, paths, name, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS,
2877 &i, changes, n_changes);
2878 if (r < 0)
2879 return r;
2880
2881 r = install_info_may_process(i, paths, changes, n_changes);
2882 if (r < 0)
2883 return r;
2884 } else
2885 r = install_info_discover(scope, minus, paths, name, SEARCH_FOLLOW_CONFIG_SYMLINKS,
2886 &i, changes, n_changes);
2887
2888 return r;
2889}
2890
2891int unit_file_preset(
2892 UnitFileScope scope,
2893 UnitFileFlags flags,
2894 const char *root_dir,
2895 char **files,
2896 UnitFilePresetMode mode,
2897 UnitFileChange **changes,
2898 unsigned *n_changes) {
2899
2900 _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
2901 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2902 _cleanup_(presets_freep) Presets presets = {};
2903 const char *config_path;
2904 char **i;
2905 int r;
2906
2907 assert(scope >= 0);
2908 assert(scope < _UNIT_FILE_SCOPE_MAX);
2909 assert(mode < _UNIT_FILE_PRESET_MAX);
2910
2911 r = lookup_paths_init(&paths, scope, 0, root_dir);
2912 if (r < 0)
2913 return r;
2914
2915 config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
2916 if (!config_path)
2917 return -ENXIO;
2918
2919 r = read_presets(scope, root_dir, &presets);
2920 if (r < 0)
2921 return r;
2922
2923 STRV_FOREACH(i, files) {
2924 r = preset_prepare_one(scope, &plus, &minus, &paths, *i, presets, changes, n_changes);
2925 if (r < 0)
2926 return r;
2927 }
2928
2929 return execute_preset(scope, &plus, &minus, &paths, config_path, files, mode, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
2930}
2931
2932int unit_file_preset_all(
2933 UnitFileScope scope,
2934 UnitFileFlags flags,
2935 const char *root_dir,
2936 UnitFilePresetMode mode,
2937 UnitFileChange **changes,
2938 unsigned *n_changes) {
2939
2940 _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
2941 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2942 _cleanup_(presets_freep) Presets presets = {};
2943 const char *config_path = NULL;
2944 char **i;
2945 int r;
2946
2947 assert(scope >= 0);
2948 assert(scope < _UNIT_FILE_SCOPE_MAX);
2949 assert(mode < _UNIT_FILE_PRESET_MAX);
2950
2951 r = lookup_paths_init(&paths, scope, 0, root_dir);
2952 if (r < 0)
2953 return r;
2954
2955 config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
2956 if (!config_path)
2957 return -ENXIO;
2958
2959 r = read_presets(scope, root_dir, &presets);
2960 if (r < 0)
2961 return r;
2962
2963 STRV_FOREACH(i, paths.search_path) {
2964 _cleanup_closedir_ DIR *d = NULL;
2965 struct dirent *de;
2966
2967 d = opendir(*i);
2968 if (!d) {
2969 if (errno == ENOENT)
2970 continue;
2971
2972 return -errno;
2973 }
2974
2975 FOREACH_DIRENT(de, d, return -errno) {
2976
2977 if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
2978 continue;
2979
2980 dirent_ensure_type(d, de);
2981
2982 if (!IN_SET(de->d_type, DT_LNK, DT_REG))
2983 continue;
2984
2985 /* we don't pass changes[] in, because we want to handle errors on our own */
2986 r = preset_prepare_one(scope, &plus, &minus, &paths, de->d_name, presets, NULL, 0);
2987 if (r == -ERFKILL)
2988 r = unit_file_changes_add(changes, n_changes,
2989 UNIT_FILE_IS_MASKED, de->d_name, NULL);
2990 else if (r == -ENOLINK)
2991 r = unit_file_changes_add(changes, n_changes,
2992 UNIT_FILE_IS_DANGLING, de->d_name, NULL);
2993 if (r < 0)
2994 return r;
2995 }
2996 }
2997
2998 return execute_preset(scope, &plus, &minus, &paths, config_path, NULL, mode, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
2999}
3000
3001static void unit_file_list_free_one(UnitFileList *f) {
3002 if (!f)
3003 return;
3004
3005 free(f->path);
3006 free(f);
3007}
3008
3009Hashmap* unit_file_list_free(Hashmap *h) {
3010 UnitFileList *i;
3011
3012 while ((i = hashmap_steal_first(h)))
3013 unit_file_list_free_one(i);
3014
3015 return hashmap_free(h);
3016}
3017
3018DEFINE_TRIVIAL_CLEANUP_FUNC(UnitFileList*, unit_file_list_free_one);
3019
3020int unit_file_get_list(
3021 UnitFileScope scope,
3022 const char *root_dir,
3023 Hashmap *h,
3024 char **states,
3025 char **patterns) {
3026
3027 _cleanup_lookup_paths_free_ LookupPaths paths = {};
3028 char **i;
3029 int r;
3030
3031 assert(scope >= 0);
3032 assert(scope < _UNIT_FILE_SCOPE_MAX);
3033 assert(h);
3034
3035 r = lookup_paths_init(&paths, scope, 0, root_dir);
3036 if (r < 0)
3037 return r;
3038
3039 STRV_FOREACH(i, paths.search_path) {
3040 _cleanup_closedir_ DIR *d = NULL;
3041 struct dirent *de;
3042
3043 d = opendir(*i);
3044 if (!d) {
3045 if (errno == ENOENT)
3046 continue;
3047 if (IN_SET(errno, ENOTDIR, EACCES)) {
3048 log_debug_errno(errno, "Failed to open \"%s\": %m", *i);
3049 continue;
3050 }
3051
3052 return -errno;
3053 }
3054
3055 FOREACH_DIRENT(de, d, return -errno) {
3056 _cleanup_(unit_file_list_free_onep) UnitFileList *f = NULL;
3057
3058 if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
3059 continue;
3060
3061 if (!strv_fnmatch_or_empty(patterns, de->d_name, FNM_NOESCAPE))
3062 continue;
3063
3064 if (hashmap_get(h, de->d_name))
3065 continue;
3066
3067 dirent_ensure_type(d, de);
3068
3069 if (!IN_SET(de->d_type, DT_LNK, DT_REG))
3070 continue;
3071
3072 f = new0(UnitFileList, 1);
3073 if (!f)
3074 return -ENOMEM;
3075
3076 f->path = path_make_absolute(de->d_name, *i);
3077 if (!f->path)
3078 return -ENOMEM;
3079
3080 r = unit_file_lookup_state(scope, &paths, de->d_name, &f->state);
3081 if (r < 0)
3082 f->state = UNIT_FILE_BAD;
3083
3084 if (!strv_isempty(states) &&
3085 !strv_contains(states, unit_file_state_to_string(f->state)))
3086 continue;
3087
3088 r = hashmap_put(h, basename(f->path), f);
3089 if (r < 0)
3090 return r;
3091
3092 f = NULL; /* prevent cleanup */
3093 }
3094 }
3095
3096 return 0;
3097}
3098
3099static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
3100 [UNIT_FILE_ENABLED] = "enabled",
3101 [UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtime",
3102 [UNIT_FILE_LINKED] = "linked",
3103 [UNIT_FILE_LINKED_RUNTIME] = "linked-runtime",
3104 [UNIT_FILE_MASKED] = "masked",
3105 [UNIT_FILE_MASKED_RUNTIME] = "masked-runtime",
3106 [UNIT_FILE_STATIC] = "static",
3107 [UNIT_FILE_DISABLED] = "disabled",
3108 [UNIT_FILE_INDIRECT] = "indirect",
3109 [UNIT_FILE_GENERATED] = "generated",
3110 [UNIT_FILE_TRANSIENT] = "transient",
3111 [UNIT_FILE_BAD] = "bad",
3112};
3113
3114DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);
3115
3116static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = {
3117 [UNIT_FILE_SYMLINK] = "symlink",
3118 [UNIT_FILE_UNLINK] = "unlink",
3119 [UNIT_FILE_IS_MASKED] = "masked",
3120 [UNIT_FILE_IS_DANGLING] = "dangling",
3121};
3122
3123DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
3124
3125static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MAX] = {
3126 [UNIT_FILE_PRESET_FULL] = "full",
3127 [UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
3128 [UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
3129};
3130
3131DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode, UnitFilePresetMode);