1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty <of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
32 #include "path-util.h"
33 #include "path-lookup.h"
35 #include "unit-name.h"
37 #include "conf-parser.h"
38 #include "conf-files.h"
39 #include "specifier.h"
40 #include "install-printf.h"
44 OrderedHashmap *will_install;
45 OrderedHashmap *have_installed;
48 static int in_search_path(const char *path, char **search) {
49 _cleanup_free_ char *parent = NULL;
54 r = path_get_parent(path, &parent);
58 return strv_contains(search, parent);
61 static int get_config_path(UnitFileScope scope, bool runtime, const char *root_dir, char **ret) {
66 assert(scope < _UNIT_FILE_SCOPE_MAX);
71 case UNIT_FILE_SYSTEM:
74 p = path_join(root_dir, "/run/systemd/system", NULL);
76 p = path_join(root_dir, SYSTEM_CONFIG_UNIT_PATH, NULL);
79 case UNIT_FILE_GLOBAL:
85 p = strdup("/run/systemd/user");
87 p = strdup(USER_CONFIG_UNIT_PATH);
96 r = user_runtime_dir(&p);
98 r = user_config_home(&p);
101 return r < 0 ? r : -ENOENT;
106 assert_not_reached("Bad scope");
116 static int add_file_change(
117 UnitFileChange **changes,
119 UnitFileChangeType type,
121 const char *source) {
127 assert(!changes == !n_changes);
132 c = realloc(*changes, (*n_changes + 1) * sizeof(UnitFileChange));
140 c[i].path = strdup(path);
144 path_kill_slashes(c[i].path);
147 c[i].source = strdup(source);
153 path_kill_slashes(c[i].path);
161 static int mark_symlink_for_removal(
162 Set **remove_symlinks_to,
170 r = set_ensure_allocated(remove_symlinks_to, &string_hash_ops);
178 path_kill_slashes(n);
180 r = set_consume(*remove_symlinks_to, n);
182 return r == -EEXIST ? 0 : r;
187 static int remove_marked_symlinks_fd(
188 Set *remove_symlinks_to,
191 const char *config_path,
193 UnitFileChange **changes,
195 char** instance_whitelist) {
197 _cleanup_closedir_ DIR *d = NULL;
200 assert(remove_symlinks_to);
219 if (!de && errno != 0) {
227 if (hidden_file(de->d_name))
230 dirent_ensure_type(d, de);
232 if (de->d_type == DT_DIR) {
234 _cleanup_free_ char *p = NULL;
236 nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
246 p = path_make_absolute(de->d_name, path);
252 /* This will close nfd, regardless whether it succeeds or not */
253 q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, deleted, changes, n_changes, instance_whitelist);
257 } else if (de->d_type == DT_LNK) {
258 _cleanup_free_ char *p = NULL, *dest = NULL;
262 if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
265 if (unit_name_is_instance(de->d_name) &&
266 instance_whitelist &&
267 !strv_contains(instance_whitelist, de->d_name)) {
269 _cleanup_free_ char *w;
271 /* OK, the file is not listed directly
272 * in the whitelist, so let's check if
273 * the template of it might be
276 w = unit_name_template(de->d_name);
280 if (!strv_contains(instance_whitelist, w))
284 p = path_make_absolute(de->d_name, path);
288 q = readlink_and_canonicalize(p, &dest);
299 set_get(remove_symlinks_to, dest) ||
300 set_get(remove_symlinks_to, basename(dest));
305 if (unlink(p) < 0 && errno != ENOENT) {
311 path_kill_slashes(p);
312 rmdir_parents(p, config_path);
313 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, p, NULL);
315 if (!set_get(remove_symlinks_to, p)) {
317 q = mark_symlink_for_removal(&remove_symlinks_to, p);
330 static int remove_marked_symlinks(
331 Set *remove_symlinks_to,
332 const char *config_path,
333 UnitFileChange **changes,
335 char** instance_whitelist) {
337 _cleanup_close_ int fd = -1;
343 if (set_size(remove_symlinks_to) <= 0)
346 fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
354 cfd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
360 /* This takes possession of cfd and closes it */
361 q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, &deleted, changes, n_changes, instance_whitelist);
369 static int find_symlinks_fd(
373 const char *config_path,
374 bool *same_name_link) {
377 _cleanup_closedir_ DIR *d = NULL;
383 assert(same_name_link);
396 if (!de && errno != 0)
402 if (hidden_file(de->d_name))
405 dirent_ensure_type(d, de);
407 if (de->d_type == DT_DIR) {
409 _cleanup_free_ char *p = NULL;
411 nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
421 p = path_make_absolute(de->d_name, path);
427 /* This will close nfd, regardless whether it succeeds or not */
428 q = find_symlinks_fd(name, nfd, p, config_path, same_name_link);
434 } else if (de->d_type == DT_LNK) {
435 _cleanup_free_ char *p = NULL, *dest = NULL;
436 bool found_path, found_dest, b = false;
439 /* Acquire symlink name */
440 p = path_make_absolute(de->d_name, path);
444 /* Acquire symlink destination */
445 q = readlink_and_canonicalize(p, &dest);
455 /* Check if the symlink itself matches what we
457 if (path_is_absolute(name))
458 found_path = path_equal(p, name);
460 found_path = streq(de->d_name, name);
462 /* Check if what the symlink points to
463 * matches what we are looking for */
464 if (path_is_absolute(name))
465 found_dest = path_equal(dest, name);
467 found_dest = streq(basename(dest), name);
469 if (found_path && found_dest) {
470 _cleanup_free_ char *t = NULL;
472 /* Filter out same name links in the main
474 t = path_make_absolute(name, config_path);
478 b = path_equal(t, p);
482 *same_name_link = true;
483 else if (found_path || found_dest)
489 static int find_symlinks(
491 const char *config_path,
492 bool *same_name_link) {
498 assert(same_name_link);
500 fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
507 /* This takes possession of fd and closes it */
508 return find_symlinks_fd(name, fd, config_path, config_path, same_name_link);
511 static int find_symlinks_in_scope(
513 const char *root_dir,
515 UnitFileState *state) {
518 _cleanup_free_ char *path = NULL;
519 bool same_name_link_runtime = false, same_name_link = false;
522 assert(scope < _UNIT_FILE_SCOPE_MAX);
525 /* First look in runtime config path */
526 r = get_config_path(scope, true, root_dir, &path);
530 r = find_symlinks(name, path, &same_name_link_runtime);
534 *state = UNIT_FILE_ENABLED_RUNTIME;
538 /* Then look in the normal config path */
539 r = get_config_path(scope, false, root_dir, &path);
543 r = find_symlinks(name, path, &same_name_link);
547 *state = UNIT_FILE_ENABLED;
551 /* Hmm, we didn't find it, but maybe we found the same name
553 if (same_name_link_runtime) {
554 *state = UNIT_FILE_LINKED_RUNTIME;
556 } else if (same_name_link) {
557 *state = UNIT_FILE_LINKED;
567 const char *root_dir,
570 UnitFileChange **changes,
571 unsigned *n_changes) {
574 _cleanup_free_ char *prefix = NULL;
578 assert(scope < _UNIT_FILE_SCOPE_MAX);
580 r = get_config_path(scope, runtime, root_dir, &prefix);
584 STRV_FOREACH(i, files) {
585 _cleanup_free_ char *path = NULL;
587 if (!unit_name_is_valid(*i, TEMPLATE_VALID)) {
593 path = path_make_absolute(*i, prefix);
599 if (symlink("/dev/null", path) >= 0) {
600 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null");
604 if (errno == EEXIST) {
606 if (null_or_empty_path(path) > 0)
610 if (symlink_atomic("/dev/null", path) >= 0) {
611 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
612 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null");
628 int unit_file_unmask(
631 const char *root_dir,
633 UnitFileChange **changes,
634 unsigned *n_changes) {
636 char **i, *config_path = NULL;
638 Set *remove_symlinks_to = NULL;
641 assert(scope < _UNIT_FILE_SCOPE_MAX);
643 r = get_config_path(scope, runtime, root_dir, &config_path);
647 STRV_FOREACH(i, files) {
648 _cleanup_free_ char *path = NULL;
650 if (!unit_name_is_valid(*i, TEMPLATE_VALID)) {
656 path = path_make_absolute(*i, config_path);
662 q = null_or_empty_path(path);
664 if (unlink(path) < 0)
667 q = mark_symlink_for_removal(&remove_symlinks_to, path);
668 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
672 if (q != -ENOENT && r == 0)
678 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
682 set_free_free(remove_symlinks_to);
691 const char *root_dir,
694 UnitFileChange **changes,
695 unsigned *n_changes) {
697 _cleanup_lookup_paths_free_ LookupPaths paths = {};
699 _cleanup_free_ char *config_path = NULL;
703 assert(scope < _UNIT_FILE_SCOPE_MAX);
705 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
709 r = get_config_path(scope, runtime, root_dir, &config_path);
713 STRV_FOREACH(i, files) {
714 _cleanup_free_ char *path = NULL;
720 if (!path_is_absolute(*i) ||
721 !unit_name_is_valid(fn, TEMPLATE_VALID)) {
727 if (lstat(*i, &st) < 0) {
733 if (!S_ISREG(st.st_mode)) {
738 q = in_search_path(*i, paths.unit_path);
745 path = path_make_absolute(fn, config_path);
749 if (symlink(*i, path) >= 0) {
750 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, *i);
754 if (errno == EEXIST) {
755 _cleanup_free_ char *dest = NULL;
757 q = readlink_and_make_absolute(path, &dest);
758 if (q < 0 && errno != ENOENT) {
764 if (q >= 0 && path_equal(dest, *i))
768 if (symlink_atomic(*i, path) >= 0) {
769 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
770 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, *i);
786 void unit_file_list_free(Hashmap *h) {
789 while ((i = hashmap_steal_first(h))) {
797 void unit_file_changes_free(UnitFileChange *changes, unsigned n_changes) {
800 assert(changes || n_changes == 0);
805 for (i = 0; i < n_changes; i++) {
806 free(changes[i].path);
807 free(changes[i].source);
813 static void install_info_free(InstallInfo *i) {
818 strv_free(i->aliases);
819 strv_free(i->wanted_by);
820 strv_free(i->required_by);
822 free(i->default_instance);
826 static void install_info_hashmap_free(OrderedHashmap *m) {
832 while ((i = ordered_hashmap_steal_first(m)))
833 install_info_free(i);
835 ordered_hashmap_free(m);
838 static void install_context_done(InstallContext *c) {
841 install_info_hashmap_free(c->will_install);
842 install_info_hashmap_free(c->have_installed);
844 c->will_install = c->have_installed = NULL;
847 static int install_info_add(
851 InstallInfo *i = NULL;
855 assert(name || path);
858 name = basename(path);
860 if (!unit_name_is_valid(name, TEMPLATE_VALID))
863 if (ordered_hashmap_get(c->have_installed, name) ||
864 ordered_hashmap_get(c->will_install, name))
867 r = ordered_hashmap_ensure_allocated(&c->will_install, &string_hash_ops);
871 i = new0(InstallInfo, 1);
875 i->name = strdup(name);
882 i->path = strdup(path);
889 r = ordered_hashmap_put(c->will_install, i->name, i);
897 install_info_free(i);
902 static int install_info_add_auto(
904 const char *name_or_path) {
907 assert(name_or_path);
909 if (path_is_absolute(name_or_path))
910 return install_info_add(c, NULL, name_or_path);
912 return install_info_add(c, name_or_path, NULL);
915 static int config_parse_also(
917 const char *filename,
920 unsigned section_line,
928 const char *word, *state;
929 InstallContext *c = data;
930 InstallInfo *i = userdata;
936 FOREACH_WORD_QUOTED(word, l, rvalue, state) {
937 _cleanup_free_ char *n;
940 n = strndup(word, l);
944 r = install_info_add(c, n, NULL);
948 r = strv_extend(&i->also, n);
953 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
954 "Trailing garbage, ignoring.");
959 static int config_parse_user(
961 const char *filename,
964 unsigned section_line,
971 InstallInfo *i = data;
979 r = install_full_printf(i, rvalue, &printed);
989 static int config_parse_default_instance(
991 const char *filename,
994 unsigned section_line,
1001 InstallInfo *i = data;
1009 r = install_full_printf(i, rvalue, &printed);
1013 if (!unit_instance_is_valid(printed)) {
1018 free(i->default_instance);
1019 i->default_instance = printed;
1024 static int unit_file_load(
1028 const char *root_dir,
1033 const ConfigTableItem items[] = {
1034 { "Install", "Alias", config_parse_strv, 0, &info->aliases },
1035 { "Install", "WantedBy", config_parse_strv, 0, &info->wanted_by },
1036 { "Install", "RequiredBy", config_parse_strv, 0, &info->required_by },
1037 { "Install", "DefaultInstance", config_parse_default_instance, 0, info },
1038 { "Install", "Also", config_parse_also, 0, c },
1039 { "Exec", "User", config_parse_user, 0, info },
1043 _cleanup_fclose_ FILE *f = NULL;
1050 if (!isempty(root_dir))
1051 path = strappenda(root_dir, "/", path);
1054 r = access(path, F_OK) ? -errno : 0;
1058 fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|(allow_symlink ? 0 : O_NOFOLLOW));
1062 f = fdopen(fd, "re");
1068 r = config_parse(NULL, path, f,
1070 config_item_table_lookup, items,
1071 true, true, false, info);
1076 *also = !strv_isempty(info->also);
1079 (int) strv_length(info->aliases) +
1080 (int) strv_length(info->wanted_by) +
1081 (int) strv_length(info->required_by);
1084 static int unit_file_search(
1088 const char *root_dir,
1101 return unit_file_load(c, info, info->path, root_dir, allow_symlink, load, also);
1105 STRV_FOREACH(p, paths->unit_path) {
1106 _cleanup_free_ char *path = NULL;
1108 path = strjoin(*p, "/", info->name, NULL);
1112 r = unit_file_load(c, info, path, root_dir, allow_symlink, load, also);
1118 if (r != -ENOENT && r != -ELOOP)
1122 if (unit_name_is_instance(info->name)) {
1124 /* Unit file doesn't exist, however instance
1125 * enablement was requested. We will check if it is
1126 * possible to load template unit file. */
1128 _cleanup_free_ char *template = NULL;
1130 template = unit_name_template(info->name);
1134 STRV_FOREACH(p, paths->unit_path) {
1135 _cleanup_free_ char *path = NULL;
1137 path = strjoin(*p, "/", template, NULL);
1141 r = unit_file_load(c, info, path, root_dir, allow_symlink, load, also);
1147 if (r != -ENOENT && r != -ELOOP)
1155 static int unit_file_can_install(
1157 const char *root_dir,
1162 _cleanup_(install_context_done) InstallContext c = {};
1169 r = install_info_add_auto(&c, name);
1173 assert_se(i = ordered_hashmap_first(c.will_install));
1175 r = unit_file_search(&c, i, paths, root_dir, allow_symlink, true, also);
1179 (int) strv_length(i->aliases) +
1180 (int) strv_length(i->wanted_by) +
1181 (int) strv_length(i->required_by);
1186 static int create_symlink(
1187 const char *old_path,
1188 const char *new_path,
1190 UnitFileChange **changes,
1191 unsigned *n_changes) {
1193 _cleanup_free_ char *dest = NULL;
1199 mkdir_parents_label(new_path, 0755);
1201 if (symlink(old_path, new_path) >= 0) {
1202 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
1206 if (errno != EEXIST)
1209 r = readlink_and_make_absolute(new_path, &dest);
1213 if (path_equal(dest, old_path))
1219 r = symlink_atomic(old_path, new_path);
1223 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL);
1224 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
1229 static int install_info_symlink_alias(
1231 const char *config_path,
1233 UnitFileChange **changes,
1234 unsigned *n_changes) {
1240 assert(config_path);
1242 STRV_FOREACH(s, i->aliases) {
1243 _cleanup_free_ char *alias_path = NULL, *dst = NULL;
1245 q = install_full_printf(i, *s, &dst);
1249 alias_path = path_make_absolute(dst, config_path);
1253 q = create_symlink(i->path, alias_path, force, changes, n_changes);
1261 static int install_info_symlink_wants(
1263 const char *config_path,
1267 UnitFileChange **changes,
1268 unsigned *n_changes) {
1270 _cleanup_free_ char *buf = NULL;
1276 assert(config_path);
1278 if (unit_name_is_template(i->name)) {
1280 /* Don't install any symlink if there's no default
1281 * instance configured */
1283 if (!i->default_instance)
1286 buf = unit_name_replace_instance(i->name, i->default_instance);
1294 STRV_FOREACH(s, list) {
1295 _cleanup_free_ char *path = NULL, *dst = NULL;
1297 q = install_full_printf(i, *s, &dst);
1301 if (!unit_name_is_valid(dst, TEMPLATE_VALID)) {
1306 path = strjoin(config_path, "/", dst, suffix, n, NULL);
1310 q = create_symlink(i->path, path, force, changes, n_changes);
1318 static int install_info_symlink_link(
1321 const char *config_path,
1322 const char *root_dir,
1324 UnitFileChange **changes,
1325 unsigned *n_changes) {
1327 _cleanup_free_ char *path = NULL;
1332 assert(config_path);
1335 r = in_search_path(i->path, paths->unit_path);
1339 path = strjoin(config_path, "/", i->name, NULL);
1343 return create_symlink(i->path, path, force, changes, n_changes);
1346 static int install_info_apply(
1349 const char *config_path,
1350 const char *root_dir,
1352 UnitFileChange **changes,
1353 unsigned *n_changes) {
1359 assert(config_path);
1361 r = install_info_symlink_alias(i, config_path, force, changes, n_changes);
1363 q = install_info_symlink_wants(i, config_path, i->wanted_by, ".wants/", force, changes, n_changes);
1367 q = install_info_symlink_wants(i, config_path, i->required_by, ".requires/", force, changes, n_changes);
1371 q = install_info_symlink_link(i, paths, config_path, root_dir, force, changes, n_changes);
1378 static int install_context_apply(
1381 const char *config_path,
1382 const char *root_dir,
1384 UnitFileChange **changes,
1385 unsigned *n_changes) {
1392 assert(config_path);
1394 if (!ordered_hashmap_isempty(c->will_install)) {
1395 r = ordered_hashmap_ensure_allocated(&c->have_installed, &string_hash_ops);
1399 r = ordered_hashmap_reserve(c->have_installed, ordered_hashmap_size(c->will_install));
1405 while ((i = ordered_hashmap_first(c->will_install))) {
1406 assert_se(ordered_hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
1408 q = unit_file_search(c, i, paths, root_dir, false, true, NULL);
1417 q = install_info_apply(i, paths, config_path, root_dir, force, changes, n_changes);
1418 if (r >= 0 && q < 0)
1425 static int install_context_mark_for_removal(
1428 Set **remove_symlinks_to,
1429 const char *config_path,
1430 const char *root_dir) {
1437 assert(config_path);
1439 /* Marks all items for removal */
1441 if (!ordered_hashmap_isempty(c->will_install)) {
1442 r = ordered_hashmap_ensure_allocated(&c->have_installed, &string_hash_ops);
1446 r = ordered_hashmap_reserve(c->have_installed, ordered_hashmap_size(c->will_install));
1452 while ((i = ordered_hashmap_first(c->will_install))) {
1453 assert_se(ordered_hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
1455 q = unit_file_search(c, i, paths, root_dir, false, true, NULL);
1466 if (unit_name_is_instance(i->name)) {
1470 unit_file = basename(i->path);
1472 if (unit_name_is_instance(unit_file))
1473 /* unit file named as instance exists, thus all symlinks
1474 * pointing to it will be removed */
1475 q = mark_symlink_for_removal(remove_symlinks_to, i->name);
1477 /* does not exist, thus we will mark for removal symlinks
1478 * to template unit file */
1479 q = mark_symlink_for_removal(remove_symlinks_to, unit_file);
1481 /* If i->path is not set, it means that we didn't actually find
1482 * the unit file. But we can still remove symlinks to the
1483 * nonexistent template. */
1484 unit_file = unit_name_template(i->name);
1488 q = mark_symlink_for_removal(remove_symlinks_to, unit_file);
1492 q = mark_symlink_for_removal(remove_symlinks_to, i->name);
1494 if (r >= 0 && q < 0)
1501 int unit_file_add_dependency(
1502 UnitFileScope scope,
1504 const char *root_dir,
1509 UnitFileChange **changes,
1510 unsigned *n_changes) {
1512 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1513 _cleanup_(install_context_done) InstallContext c = {};
1514 _cleanup_free_ char *config_path = NULL;
1520 assert(scope < _UNIT_FILE_SCOPE_MAX);
1522 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1526 r = get_config_path(scope, runtime, root_dir, &config_path);
1530 STRV_FOREACH(i, files) {
1531 UnitFileState state;
1533 state = unit_file_get_state(scope, root_dir, *i);
1535 return log_error_errno(state, "Failed to get unit file state for %s: %m", *i);
1537 if (state == UNIT_FILE_MASKED || state == UNIT_FILE_MASKED_RUNTIME) {
1538 log_error("Failed to enable unit: Unit %s is masked", *i);
1542 r = install_info_add_auto(&c, *i);
1547 if (!ordered_hashmap_isempty(c.will_install)) {
1548 r = ordered_hashmap_ensure_allocated(&c.have_installed, &string_hash_ops);
1552 r = ordered_hashmap_reserve(c.have_installed, ordered_hashmap_size(c.will_install));
1557 while ((info = ordered_hashmap_first(c.will_install))) {
1558 assert_se(ordered_hashmap_move_one(c.have_installed, c.will_install, info->name) == 0);
1560 r = unit_file_search(&c, info, &paths, root_dir, false, false, NULL);
1564 if (dep == UNIT_WANTS)
1565 r = strv_extend(&info->wanted_by, target);
1566 else if (dep == UNIT_REQUIRES)
1567 r = strv_extend(&info->required_by, target);
1574 r = install_info_apply(info, &paths, config_path, root_dir, force, changes, n_changes);
1582 int unit_file_enable(
1583 UnitFileScope scope,
1585 const char *root_dir,
1588 UnitFileChange **changes,
1589 unsigned *n_changes) {
1591 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1592 _cleanup_(install_context_done) InstallContext c = {};
1594 _cleanup_free_ char *config_path = NULL;
1598 assert(scope < _UNIT_FILE_SCOPE_MAX);
1600 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1604 r = get_config_path(scope, runtime, root_dir, &config_path);
1608 STRV_FOREACH(i, files) {
1609 UnitFileState state;
1611 /* We only want to know if this unit is masked, so we ignore
1612 * errors from unit_file_get_state, deferring other checks.
1613 * This allows templated units to be enabled on the fly. */
1614 state = unit_file_get_state(scope, root_dir, *i);
1615 if (state == UNIT_FILE_MASKED || state == UNIT_FILE_MASKED_RUNTIME) {
1616 log_error("Failed to enable unit: Unit %s is masked", *i);
1620 r = install_info_add_auto(&c, *i);
1625 /* This will return the number of symlink rules that were
1626 supposed to be created, not the ones actually created. This is
1627 useful to determine whether the passed files had any
1628 installation data at all. */
1630 return install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes);
1633 int unit_file_disable(
1634 UnitFileScope scope,
1636 const char *root_dir,
1638 UnitFileChange **changes,
1639 unsigned *n_changes) {
1641 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1642 _cleanup_(install_context_done) InstallContext c = {};
1644 _cleanup_free_ char *config_path = NULL;
1645 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
1649 assert(scope < _UNIT_FILE_SCOPE_MAX);
1651 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1655 r = get_config_path(scope, runtime, root_dir, &config_path);
1659 STRV_FOREACH(i, files) {
1660 r = install_info_add_auto(&c, *i);
1665 r = install_context_mark_for_removal(&c, &paths, &remove_symlinks_to, config_path, root_dir);
1667 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
1674 int unit_file_reenable(
1675 UnitFileScope scope,
1677 const char *root_dir,
1680 UnitFileChange **changes,
1681 unsigned *n_changes) {
1684 r = unit_file_disable(scope, runtime, root_dir, files,
1685 changes, n_changes);
1689 return unit_file_enable(scope, runtime, root_dir, files, force,
1690 changes, n_changes);
1693 int unit_file_set_default(
1694 UnitFileScope scope,
1695 const char *root_dir,
1698 UnitFileChange **changes,
1699 unsigned *n_changes) {
1701 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1702 _cleanup_(install_context_done) InstallContext c = {};
1703 _cleanup_free_ char *config_path = NULL;
1706 InstallInfo *i = NULL;
1709 assert(scope < _UNIT_FILE_SCOPE_MAX);
1712 if (unit_name_to_type(file) != UNIT_TARGET)
1715 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1719 r = get_config_path(scope, false, root_dir, &config_path);
1723 r = install_info_add_auto(&c, file);
1727 assert_se(i = ordered_hashmap_first(c.will_install));
1729 r = unit_file_search(&c, i, &paths, root_dir, false, true, NULL);
1733 path = strappenda(config_path, "/" SPECIAL_DEFAULT_TARGET);
1735 r = create_symlink(i->path, path, force, changes, n_changes);
1742 int unit_file_get_default(
1743 UnitFileScope scope,
1744 const char *root_dir,
1747 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1752 assert(scope < _UNIT_FILE_SCOPE_MAX);
1755 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1759 STRV_FOREACH(p, paths.unit_path) {
1760 _cleanup_free_ char *path = NULL, *tmp = NULL;
1763 path = path_join(root_dir, *p, SPECIAL_DEFAULT_TARGET);
1767 r = readlink_malloc(path, &tmp);
1770 else if (r == -EINVAL)
1772 n = strdup(SPECIAL_DEFAULT_TARGET);
1776 n = strdup(basename(tmp));
1788 UnitFileState unit_file_get_state(
1789 UnitFileScope scope,
1790 const char *root_dir,
1793 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1794 UnitFileState state = _UNIT_FILE_STATE_INVALID;
1796 _cleanup_free_ char *path = NULL;
1800 assert(scope < _UNIT_FILE_SCOPE_MAX);
1803 if (root_dir && scope != UNIT_FILE_SYSTEM)
1806 if (!unit_name_is_valid(name, TEMPLATE_VALID))
1809 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1813 STRV_FOREACH(i, paths.unit_path) {
1821 path = path_join(root_dir, *i, name);
1826 partial = path + strlen(root_dir);
1831 * Search for a unit file in our default paths, to
1832 * be sure, that there are no broken symlinks.
1834 if (lstat(path, &st) < 0) {
1836 if (errno != ENOENT)
1839 if (!unit_name_is_instance(name))
1842 if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode))
1845 r = null_or_empty_path(path);
1846 if (r < 0 && r != -ENOENT)
1849 state = path_startswith(*i, "/run") ?
1850 UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
1855 r = find_symlinks_in_scope(scope, root_dir, name, &state);
1861 r = unit_file_can_install(&paths, root_dir, partial, true, &also);
1862 if (r < 0 && errno != ENOENT)
1865 return UNIT_FILE_DISABLED;
1868 return UNIT_FILE_INDIRECT;
1869 return UNIT_FILE_STATIC;
1873 return r < 0 ? r : state;
1876 int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name) {
1877 _cleanup_strv_free_ char **files = NULL;
1882 assert(scope < _UNIT_FILE_SCOPE_MAX);
1885 if (scope == UNIT_FILE_SYSTEM)
1886 r = conf_files_list(&files, ".preset", root_dir,
1887 "/etc/systemd/system-preset",
1888 "/usr/local/lib/systemd/system-preset",
1889 "/usr/lib/systemd/system-preset",
1890 #ifdef HAVE_SPLIT_USR
1891 "/lib/systemd/system-preset",
1894 else if (scope == UNIT_FILE_GLOBAL)
1895 r = conf_files_list(&files, ".preset", root_dir,
1896 "/etc/systemd/user-preset",
1897 "/usr/local/lib/systemd/user-preset",
1898 "/usr/lib/systemd/user-preset",
1906 STRV_FOREACH(p, files) {
1907 _cleanup_fclose_ FILE *f;
1909 f = fopen(*p, "re");
1911 if (errno == ENOENT)
1918 char line[LINE_MAX], *l;
1920 if (!fgets(line, sizeof(line), f))
1927 if (strchr(COMMENTS "\n", *l))
1930 if (first_word(l, "enable")) {
1932 l += strspn(l, WHITESPACE);
1934 if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
1935 log_debug("Preset file says enable %s.", name);
1939 } else if (first_word(l, "disable")) {
1941 l += strspn(l, WHITESPACE);
1943 if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
1944 log_debug("Preset file says disable %s.", name);
1949 log_debug("Couldn't parse line '%s'", l);
1953 /* Default is "enable" */
1954 log_debug("Preset file doesn't say anything about %s, enabling.", name);
1958 int unit_file_preset(
1959 UnitFileScope scope,
1961 const char *root_dir,
1963 UnitFilePresetMode mode,
1965 UnitFileChange **changes,
1966 unsigned *n_changes) {
1968 _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
1969 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1970 _cleanup_free_ char *config_path = NULL;
1975 assert(scope < _UNIT_FILE_SCOPE_MAX);
1976 assert(mode < _UNIT_FILE_PRESET_MAX);
1978 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1982 r = get_config_path(scope, runtime, root_dir, &config_path);
1986 STRV_FOREACH(i, files) {
1988 if (!unit_name_is_valid(*i, TEMPLATE_VALID))
1991 r = unit_file_query_preset(scope, root_dir, *i);
1995 if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
1996 r = install_info_add_auto(&plus, *i);
1997 else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
1998 r = install_info_add_auto(&minus, *i);
2007 if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
2008 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
2010 r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
2012 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
2017 if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
2018 /* Returns number of symlinks that where supposed to be installed. */
2019 q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
2027 int unit_file_preset_all(
2028 UnitFileScope scope,
2030 const char *root_dir,
2031 UnitFilePresetMode mode,
2033 UnitFileChange **changes,
2034 unsigned *n_changes) {
2036 _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
2037 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2038 _cleanup_free_ char *config_path = NULL;
2043 assert(scope < _UNIT_FILE_SCOPE_MAX);
2044 assert(mode < _UNIT_FILE_PRESET_MAX);
2046 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
2050 r = get_config_path(scope, runtime, root_dir, &config_path);
2054 STRV_FOREACH(i, paths.unit_path) {
2055 _cleanup_closedir_ DIR *d = NULL;
2056 _cleanup_free_ char *units_dir;
2058 units_dir = path_join(root_dir, *i, NULL);
2062 d = opendir(units_dir);
2064 if (errno == ENOENT)
2075 if (!de && errno != 0)
2081 if (hidden_file(de->d_name))
2084 if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
2087 dirent_ensure_type(d, de);
2089 if (de->d_type != DT_REG)
2092 r = unit_file_query_preset(scope, root_dir, de->d_name);
2096 if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
2097 r = install_info_add_auto(&plus, de->d_name);
2098 else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
2099 r = install_info_add_auto(&minus, de->d_name);
2109 if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
2110 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
2112 r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
2114 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, NULL);
2119 if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
2120 q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
2128 static void unit_file_list_free_one(UnitFileList *f) {
2136 DEFINE_TRIVIAL_CLEANUP_FUNC(UnitFileList*, unit_file_list_free_one);
2138 int unit_file_get_list(
2139 UnitFileScope scope,
2140 const char *root_dir,
2143 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2148 assert(scope < _UNIT_FILE_SCOPE_MAX);
2151 if (root_dir && scope != UNIT_FILE_SYSTEM)
2155 r = access(root_dir, F_OK);
2160 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
2164 STRV_FOREACH(i, paths.unit_path) {
2165 _cleanup_closedir_ DIR *d = NULL;
2166 _cleanup_free_ char *units_dir;
2168 units_dir = path_join(root_dir, *i, NULL);
2172 d = opendir(units_dir);
2174 if (errno == ENOENT)
2181 _cleanup_(unit_file_list_free_onep) UnitFileList *f = NULL;
2183 _cleanup_free_ char *path = NULL;
2187 if (!de && errno != 0)
2193 if (hidden_file(de->d_name))
2196 if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
2199 if (hashmap_get(h, de->d_name))
2202 dirent_ensure_type(d, de);
2204 if (!IN_SET(de->d_type, DT_LNK, DT_REG))
2207 f = new0(UnitFileList, 1);
2211 f->path = path_make_absolute(de->d_name, units_dir);
2215 r = null_or_empty_path(f->path);
2216 if (r < 0 && r != -ENOENT)
2220 path_startswith(*i, "/run") ?
2221 UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
2225 r = find_symlinks_in_scope(scope, root_dir, de->d_name, &f->state);
2229 f->state = UNIT_FILE_ENABLED;
2233 path = path_make_absolute(de->d_name, *i);
2237 r = unit_file_can_install(&paths, root_dir, path, true, NULL);
2238 if (r == -EINVAL || /* Invalid setting? */
2239 r == -EBADMSG || /* Invalid format? */
2240 r == -ENOENT /* Included file not found? */)
2241 f->state = UNIT_FILE_INVALID;
2245 f->state = UNIT_FILE_DISABLED;
2247 f->state = UNIT_FILE_STATIC;
2250 r = hashmap_put(h, basename(f->path), f);
2253 f = NULL; /* prevent cleanup */
2260 static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
2261 [UNIT_FILE_ENABLED] = "enabled",
2262 [UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtime",
2263 [UNIT_FILE_LINKED] = "linked",
2264 [UNIT_FILE_LINKED_RUNTIME] = "linked-runtime",
2265 [UNIT_FILE_MASKED] = "masked",
2266 [UNIT_FILE_MASKED_RUNTIME] = "masked-runtime",
2267 [UNIT_FILE_STATIC] = "static",
2268 [UNIT_FILE_DISABLED] = "disabled",
2269 [UNIT_FILE_INDIRECT] = "indirect",
2270 [UNIT_FILE_INVALID] = "invalid",
2273 DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);
2275 static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = {
2276 [UNIT_FILE_SYMLINK] = "symlink",
2277 [UNIT_FILE_UNLINK] = "unlink",
2280 DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
2282 static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MAX] = {
2283 [UNIT_FILE_PRESET_FULL] = "full",
2284 [UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
2285 [UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
2288 DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode, UnitFilePresetMode);