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