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