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 lookup_paths_init_from_scope(LookupPaths *paths,
63 const char *root_dir) {
66 assert(scope < _UNIT_FILE_SCOPE_MAX);
70 return lookup_paths_init(paths,
71 scope == UNIT_FILE_SYSTEM ? SYSTEMD_SYSTEM : SYSTEMD_USER,
72 scope == UNIT_FILE_USER,
77 static int get_config_path(UnitFileScope scope, bool runtime, const char *root_dir, char **ret) {
82 assert(scope < _UNIT_FILE_SCOPE_MAX);
87 case UNIT_FILE_SYSTEM:
90 p = path_join(root_dir, "/run/systemd/system", NULL);
92 p = path_join(root_dir, SYSTEM_CONFIG_UNIT_PATH, NULL);
95 case UNIT_FILE_GLOBAL:
101 p = strdup("/run/systemd/user");
103 p = strdup(USER_CONFIG_UNIT_PATH);
112 r = user_runtime_dir(&p);
114 r = user_config_home(&p);
117 return r < 0 ? r : -ENOENT;
122 assert_not_reached("Bad scope");
132 static int add_file_change(
133 UnitFileChange **changes,
135 UnitFileChangeType type,
137 const char *source) {
143 assert(!changes == !n_changes);
148 c = realloc(*changes, (*n_changes + 1) * sizeof(UnitFileChange));
156 c[i].path = strdup(path);
160 path_kill_slashes(c[i].path);
163 c[i].source = strdup(source);
169 path_kill_slashes(c[i].path);
177 static int mark_symlink_for_removal(
178 Set **remove_symlinks_to,
186 r = set_ensure_allocated(remove_symlinks_to, &string_hash_ops);
194 path_kill_slashes(n);
196 r = set_consume(*remove_symlinks_to, n);
198 return r == -EEXIST ? 0 : r;
203 static int remove_marked_symlinks_fd(
204 Set *remove_symlinks_to,
207 const char *config_path,
209 UnitFileChange **changes,
211 char** instance_whitelist) {
213 _cleanup_closedir_ DIR *d = NULL;
216 assert(remove_symlinks_to);
235 if (!de && errno != 0) {
243 if (ignore_file(de->d_name))
246 dirent_ensure_type(d, de);
248 if (de->d_type == DT_DIR) {
250 _cleanup_free_ char *p = NULL;
252 nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
262 p = path_make_absolute(de->d_name, path);
268 /* This will close nfd, regardless whether it succeeds or not */
269 q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, deleted, changes, n_changes, instance_whitelist);
273 } else if (de->d_type == DT_LNK) {
274 _cleanup_free_ char *p = NULL, *dest = NULL;
278 if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
281 if (unit_name_is_instance(de->d_name) &&
282 instance_whitelist &&
283 !strv_contains(instance_whitelist, de->d_name)) {
285 _cleanup_free_ char *w;
287 /* OK, the file is not listed directly
288 * in the whitelist, so let's check if
289 * the template of it might be
292 w = unit_name_template(de->d_name);
296 if (!strv_contains(instance_whitelist, w))
300 p = path_make_absolute(de->d_name, path);
304 q = readlink_and_canonicalize(p, &dest);
315 set_get(remove_symlinks_to, dest) ||
316 set_get(remove_symlinks_to, basename(dest));
321 if (unlink(p) < 0 && errno != ENOENT) {
327 path_kill_slashes(p);
328 rmdir_parents(p, config_path);
329 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, p, NULL);
331 if (!set_get(remove_symlinks_to, p)) {
333 q = mark_symlink_for_removal(&remove_symlinks_to, p);
346 static int remove_marked_symlinks(
347 Set *remove_symlinks_to,
348 const char *config_path,
349 UnitFileChange **changes,
351 char** instance_whitelist) {
353 _cleanup_close_ int fd = -1;
359 if (set_size(remove_symlinks_to) <= 0)
362 fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
370 cfd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
376 /* This takes possession of cfd and closes it */
377 q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, &deleted, changes, n_changes, instance_whitelist);
385 static int find_symlinks_fd(
389 const char *config_path,
390 bool *same_name_link) {
393 _cleanup_closedir_ DIR *d = NULL;
399 assert(same_name_link);
412 if (!de && errno != 0)
418 if (ignore_file(de->d_name))
421 dirent_ensure_type(d, de);
423 if (de->d_type == DT_DIR) {
425 _cleanup_free_ char *p = NULL;
427 nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
437 p = path_make_absolute(de->d_name, path);
443 /* This will close nfd, regardless whether it succeeds or not */
444 q = find_symlinks_fd(name, nfd, p, config_path, same_name_link);
450 } else if (de->d_type == DT_LNK) {
451 _cleanup_free_ char *p = NULL, *dest = NULL;
452 bool found_path, found_dest, b = false;
455 /* Acquire symlink name */
456 p = path_make_absolute(de->d_name, path);
460 /* Acquire symlink destination */
461 q = readlink_and_canonicalize(p, &dest);
471 /* Check if the symlink itself matches what we
473 if (path_is_absolute(name))
474 found_path = path_equal(p, name);
476 found_path = streq(de->d_name, name);
478 /* Check if what the symlink points to
479 * matches what we are looking for */
480 if (path_is_absolute(name))
481 found_dest = path_equal(dest, name);
483 found_dest = streq(basename(dest), name);
485 if (found_path && found_dest) {
486 _cleanup_free_ char *t = NULL;
488 /* Filter out same name links in the main
490 t = path_make_absolute(name, config_path);
494 b = path_equal(t, p);
498 *same_name_link = true;
499 else if (found_path || found_dest)
505 static int find_symlinks(
507 const char *config_path,
508 bool *same_name_link) {
514 assert(same_name_link);
516 fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
523 /* This takes possession of fd and closes it */
524 return find_symlinks_fd(name, fd, config_path, config_path, same_name_link);
527 static int find_symlinks_in_scope(
529 const char *root_dir,
531 UnitFileState *state) {
534 _cleanup_free_ char *path = NULL;
535 bool same_name_link_runtime = false, same_name_link = false;
538 assert(scope < _UNIT_FILE_SCOPE_MAX);
542 /* First look in runtime config path */
543 r = get_config_path(scope, true, root_dir, &path);
547 r = find_symlinks(name, path, &same_name_link_runtime);
551 *state = UNIT_FILE_ENABLED_RUNTIME;
555 /* Then look in the normal config path */
556 r = get_config_path(scope, false, root_dir, &path);
560 r = find_symlinks(name, path, &same_name_link);
564 *state = UNIT_FILE_ENABLED;
568 /* Hmm, we didn't find it, but maybe we found the same name
570 if (same_name_link_runtime) {
571 *state = UNIT_FILE_LINKED_RUNTIME;
573 } else if (same_name_link) {
574 *state = UNIT_FILE_LINKED;
584 const char *root_dir,
587 UnitFileChange **changes,
588 unsigned *n_changes) {
591 _cleanup_free_ char *prefix = NULL;
595 assert(scope < _UNIT_FILE_SCOPE_MAX);
597 r = get_config_path(scope, runtime, root_dir, &prefix);
601 STRV_FOREACH(i, files) {
602 _cleanup_free_ char *path = NULL;
604 if (!unit_name_is_valid(*i, TEMPLATE_VALID)) {
610 path = path_make_absolute(*i, prefix);
616 if (symlink("/dev/null", path) >= 0) {
617 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null");
621 if (errno == EEXIST) {
623 if (null_or_empty_path(path) > 0)
627 if (symlink_atomic("/dev/null", path) >= 0) {
628 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
629 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null");
645 int unit_file_unmask(
648 const char *root_dir,
650 UnitFileChange **changes,
651 unsigned *n_changes) {
653 char **i, *config_path = NULL;
655 Set *remove_symlinks_to = NULL;
658 assert(scope < _UNIT_FILE_SCOPE_MAX);
660 r = get_config_path(scope, runtime, root_dir, &config_path);
664 STRV_FOREACH(i, files) {
667 if (!unit_name_is_valid(*i, TEMPLATE_VALID)) {
673 path = path_make_absolute(*i, config_path);
679 q = null_or_empty_path(path);
681 if (unlink(path) >= 0) {
682 mark_symlink_for_removal(&remove_symlinks_to, path);
683 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
692 if (q != -ENOENT && r == 0)
700 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
704 set_free_free(remove_symlinks_to);
713 const char *root_dir,
716 UnitFileChange **changes,
717 unsigned *n_changes) {
719 _cleanup_lookup_paths_free_ LookupPaths paths = {};
721 _cleanup_free_ char *config_path = NULL;
725 assert(scope < _UNIT_FILE_SCOPE_MAX);
727 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
731 r = get_config_path(scope, runtime, root_dir, &config_path);
735 STRV_FOREACH(i, files) {
736 _cleanup_free_ char *path = NULL;
742 if (!path_is_absolute(*i) ||
743 !unit_name_is_valid(fn, TEMPLATE_VALID)) {
749 if (lstat(*i, &st) < 0) {
755 if (!S_ISREG(st.st_mode)) {
760 q = in_search_path(*i, paths.unit_path);
767 path = path_make_absolute(fn, config_path);
771 if (symlink(*i, path) >= 0) {
772 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, *i);
776 if (errno == EEXIST) {
777 _cleanup_free_ char *dest = NULL;
779 q = readlink_and_make_absolute(path, &dest);
780 if (q < 0 && errno != ENOENT) {
786 if (q >= 0 && path_equal(dest, *i))
790 if (symlink_atomic(*i, path) >= 0) {
791 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
792 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, *i);
808 void unit_file_list_free(Hashmap *h) {
811 while ((i = hashmap_steal_first(h))) {
819 void unit_file_changes_free(UnitFileChange *changes, unsigned n_changes) {
822 assert(changes || n_changes == 0);
827 for (i = 0; i < n_changes; i++) {
828 free(changes[i].path);
829 free(changes[i].source);
835 static void install_info_free(InstallInfo *i) {
840 strv_free(i->aliases);
841 strv_free(i->wanted_by);
842 strv_free(i->required_by);
843 free(i->default_instance);
847 static void install_info_hashmap_free(OrderedHashmap *m) {
853 while ((i = ordered_hashmap_steal_first(m)))
854 install_info_free(i);
856 ordered_hashmap_free(m);
859 static void install_context_done(InstallContext *c) {
862 install_info_hashmap_free(c->will_install);
863 install_info_hashmap_free(c->have_installed);
865 c->will_install = c->have_installed = NULL;
868 static int install_info_add(
872 InstallInfo *i = NULL;
876 assert(name || path);
879 name = basename(path);
881 if (!unit_name_is_valid(name, TEMPLATE_VALID))
884 if (ordered_hashmap_get(c->have_installed, name) ||
885 ordered_hashmap_get(c->will_install, name))
888 r = ordered_hashmap_ensure_allocated(&c->will_install, &string_hash_ops);
892 i = new0(InstallInfo, 1);
896 i->name = strdup(name);
903 i->path = strdup(path);
910 r = ordered_hashmap_put(c->will_install, i->name, i);
918 install_info_free(i);
923 static int install_info_add_auto(
925 const char *name_or_path) {
928 assert(name_or_path);
930 if (path_is_absolute(name_or_path))
931 return install_info_add(c, NULL, name_or_path);
933 return install_info_add(c, name_or_path, NULL);
936 static int config_parse_also(
938 const char *filename,
941 unsigned section_line,
949 const char *word, *state;
950 InstallContext *c = data;
956 FOREACH_WORD_QUOTED(word, l, rvalue, state) {
957 _cleanup_free_ char *n;
960 n = strndup(word, l);
964 r = install_info_add(c, n, NULL);
969 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
970 "Trailing garbage, ignoring.");
975 static int config_parse_user(
977 const char *filename,
980 unsigned section_line,
987 InstallInfo *i = data;
995 r = install_full_printf(i, rvalue, &printed);
1005 static int config_parse_default_instance(
1007 const char *filename,
1009 const char *section,
1010 unsigned section_line,
1017 InstallInfo *i = data;
1025 r = install_full_printf(i, rvalue, &printed);
1029 if (!unit_instance_is_valid(printed)) {
1034 free(i->default_instance);
1035 i->default_instance = printed;
1040 static int unit_file_load(
1044 const char *root_dir,
1048 const ConfigTableItem items[] = {
1049 { "Install", "Alias", config_parse_strv, 0, &info->aliases },
1050 { "Install", "WantedBy", config_parse_strv, 0, &info->wanted_by },
1051 { "Install", "RequiredBy", config_parse_strv, 0, &info->required_by },
1052 { "Install", "DefaultInstance", config_parse_default_instance, 0, info },
1053 { "Install", "Also", config_parse_also, 0, c },
1054 { "Exec", "User", config_parse_user, 0, info },
1058 _cleanup_fclose_ FILE *f = NULL;
1065 if (!isempty(root_dir))
1066 path = strappenda(root_dir, "/", path);
1069 r = access(path, F_OK) ? -errno : 0;
1073 fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|(allow_symlink ? 0 : O_NOFOLLOW));
1077 f = fdopen(fd, "re");
1083 r = config_parse(NULL, path, f,
1085 config_item_table_lookup, items,
1086 true, true, false, info);
1091 (int) strv_length(info->aliases) +
1092 (int) strv_length(info->wanted_by) +
1093 (int) strv_length(info->required_by);
1096 static int unit_file_search(
1100 const char *root_dir,
1112 return unit_file_load(c, info, info->path, root_dir, allow_symlink, load);
1116 STRV_FOREACH(p, paths->unit_path) {
1117 _cleanup_free_ char *path = NULL;
1119 path = strjoin(*p, "/", info->name, NULL);
1123 r = unit_file_load(c, info, path, root_dir, allow_symlink, load);
1129 if (r != -ENOENT && r != -ELOOP)
1133 if (unit_name_is_instance(info->name)) {
1135 /* Unit file doesn't exist, however instance
1136 * enablement was requested. We will check if it is
1137 * possible to load template unit file. */
1139 _cleanup_free_ char *template = NULL;
1141 template = unit_name_template(info->name);
1145 STRV_FOREACH(p, paths->unit_path) {
1146 _cleanup_free_ char *path = NULL;
1148 path = strjoin(*p, "/", template, NULL);
1152 r = unit_file_load(c, info, path, root_dir, allow_symlink, load);
1158 if (r != -ENOENT && r != -ELOOP)
1166 static int unit_file_can_install(
1168 const char *root_dir,
1170 bool allow_symlink) {
1172 _cleanup_(install_context_done) InstallContext c = {};
1179 r = install_info_add_auto(&c, name);
1183 assert_se(i = ordered_hashmap_first(c.will_install));
1185 r = unit_file_search(&c, i, paths, root_dir, allow_symlink, true);
1189 (int) strv_length(i->aliases) +
1190 (int) strv_length(i->wanted_by) +
1191 (int) strv_length(i->required_by);
1196 static int create_symlink(
1197 const char *old_path,
1198 const char *new_path,
1200 UnitFileChange **changes,
1201 unsigned *n_changes) {
1203 _cleanup_free_ char *dest = NULL;
1209 mkdir_parents_label(new_path, 0755);
1211 if (symlink(old_path, new_path) >= 0) {
1212 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
1216 if (errno != EEXIST)
1219 r = readlink_and_make_absolute(new_path, &dest);
1223 if (path_equal(dest, old_path))
1229 r = symlink_atomic(old_path, new_path);
1233 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL);
1234 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
1239 static int install_info_symlink_alias(
1241 const char *config_path,
1243 UnitFileChange **changes,
1244 unsigned *n_changes) {
1250 assert(config_path);
1252 STRV_FOREACH(s, i->aliases) {
1253 _cleanup_free_ char *alias_path = NULL, *dst = NULL;
1255 q = install_full_printf(i, *s, &dst);
1259 alias_path = path_make_absolute(dst, config_path);
1263 q = create_symlink(i->path, alias_path, force, changes, n_changes);
1271 static int install_info_symlink_wants(
1273 const char *config_path,
1277 UnitFileChange **changes,
1278 unsigned *n_changes) {
1280 _cleanup_free_ char *buf = NULL;
1286 assert(config_path);
1288 if (unit_name_is_template(i->name)) {
1290 /* Don't install any symlink if there's no default
1291 * instance configured */
1293 if (!i->default_instance)
1296 buf = unit_name_replace_instance(i->name, i->default_instance);
1304 STRV_FOREACH(s, list) {
1305 _cleanup_free_ char *path = NULL, *dst = NULL;
1307 q = install_full_printf(i, *s, &dst);
1311 if (!unit_name_is_valid(dst, TEMPLATE_VALID)) {
1316 path = strjoin(config_path, "/", dst, suffix, n, NULL);
1320 q = create_symlink(i->path, path, force, changes, n_changes);
1328 static int install_info_symlink_link(
1331 const char *config_path,
1332 const char *root_dir,
1334 UnitFileChange **changes,
1335 unsigned *n_changes) {
1337 _cleanup_free_ char *path = NULL;
1342 assert(config_path);
1345 r = in_search_path(i->path, paths->unit_path);
1349 path = strjoin(config_path, "/", i->name, NULL);
1353 return create_symlink(i->path, path, force, changes, n_changes);
1356 static int install_info_apply(
1359 const char *config_path,
1360 const char *root_dir,
1362 UnitFileChange **changes,
1363 unsigned *n_changes) {
1369 assert(config_path);
1371 r = install_info_symlink_alias(i, config_path, force, changes, n_changes);
1373 q = install_info_symlink_wants(i, config_path, i->wanted_by, ".wants/", force, changes, n_changes);
1377 q = install_info_symlink_wants(i, config_path, i->required_by, ".requires/", force, changes, n_changes);
1381 q = install_info_symlink_link(i, paths, config_path, root_dir, force, changes, n_changes);
1388 static int install_context_apply(
1391 const char *config_path,
1392 const char *root_dir,
1394 UnitFileChange **changes,
1395 unsigned *n_changes) {
1402 assert(config_path);
1404 if (!ordered_hashmap_isempty(c->will_install)) {
1405 r = ordered_hashmap_ensure_allocated(&c->have_installed, &string_hash_ops);
1409 r = ordered_hashmap_reserve(c->have_installed, ordered_hashmap_size(c->will_install));
1415 while ((i = ordered_hashmap_first(c->will_install))) {
1416 assert_se(ordered_hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
1418 q = unit_file_search(c, i, paths, root_dir, false, true);
1427 q = install_info_apply(i, paths, config_path, root_dir, force, changes, n_changes);
1428 if (r >= 0 && q < 0)
1435 static int install_context_mark_for_removal(
1438 Set **remove_symlinks_to,
1439 const char *config_path,
1440 const char *root_dir) {
1447 assert(config_path);
1449 /* Marks all items for removal */
1451 if (!ordered_hashmap_isempty(c->will_install)) {
1452 r = ordered_hashmap_ensure_allocated(&c->have_installed, &string_hash_ops);
1456 r = ordered_hashmap_reserve(c->have_installed, ordered_hashmap_size(c->will_install));
1462 while ((i = ordered_hashmap_first(c->will_install))) {
1463 assert_se(ordered_hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
1465 q = unit_file_search(c, i, paths, root_dir, false, true);
1476 if (unit_name_is_instance(i->name)) {
1480 unit_file = basename(i->path);
1482 if (unit_name_is_instance(unit_file))
1483 /* unit file named as instance exists, thus all symlinks
1484 * pointing to it will be removed */
1485 q = mark_symlink_for_removal(remove_symlinks_to, i->name);
1487 /* does not exist, thus we will mark for removal symlinks
1488 * to template unit file */
1489 q = mark_symlink_for_removal(remove_symlinks_to, unit_file);
1491 /* If i->path is not set, it means that we didn't actually find
1492 * the unit file. But we can still remove symlinks to the
1493 * nonexistent template. */
1494 unit_file = unit_name_template(i->name);
1498 q = mark_symlink_for_removal(remove_symlinks_to, unit_file);
1502 q = mark_symlink_for_removal(remove_symlinks_to, i->name);
1504 if (r >= 0 && q < 0)
1511 int unit_file_add_dependency(
1512 UnitFileScope scope,
1514 const char *root_dir,
1519 UnitFileChange **changes,
1520 unsigned *n_changes) {
1522 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1523 _cleanup_(install_context_done) InstallContext c = {};
1524 _cleanup_free_ char *config_path = NULL;
1530 assert(scope < _UNIT_FILE_SCOPE_MAX);
1532 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1536 r = get_config_path(scope, runtime, root_dir, &config_path);
1540 STRV_FOREACH(i, files) {
1541 UnitFileState state;
1543 state = unit_file_get_state(scope, root_dir, *i);
1545 log_error("Failed to get unit file state for %s: %s", *i, strerror(-state));
1549 if (state == UNIT_FILE_MASKED || state == UNIT_FILE_MASKED_RUNTIME) {
1550 log_error("Failed to enable unit: Unit %s is masked", *i);
1554 r = install_info_add_auto(&c, *i);
1559 if (!ordered_hashmap_isempty(c.will_install)) {
1560 r = ordered_hashmap_ensure_allocated(&c.have_installed, &string_hash_ops);
1564 r = ordered_hashmap_reserve(c.have_installed, ordered_hashmap_size(c.will_install));
1569 while ((info = ordered_hashmap_first(c.will_install))) {
1570 assert_se(ordered_hashmap_move_one(c.have_installed, c.will_install, info->name) == 0);
1572 r = unit_file_search(&c, info, &paths, root_dir, false, false);
1576 if (dep == UNIT_WANTS)
1577 r = strv_extend(&info->wanted_by, target);
1578 else if (dep == UNIT_REQUIRES)
1579 r = strv_extend(&info->required_by, target);
1586 r = install_info_apply(info, &paths, config_path, root_dir, force, changes, n_changes);
1594 int unit_file_enable(
1595 UnitFileScope scope,
1597 const char *root_dir,
1600 UnitFileChange **changes,
1601 unsigned *n_changes) {
1603 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1604 _cleanup_(install_context_done) InstallContext c = {};
1606 _cleanup_free_ char *config_path = NULL;
1610 assert(scope < _UNIT_FILE_SCOPE_MAX);
1612 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1616 r = get_config_path(scope, runtime, root_dir, &config_path);
1620 STRV_FOREACH(i, files) {
1621 UnitFileState state;
1623 /* We only want to know if this unit is masked, so we ignore
1624 * errors from unit_file_get_state, deferring other checks.
1625 * This allows templated units to be enabled on the fly. */
1626 state = unit_file_get_state(scope, root_dir, *i);
1627 if (state == UNIT_FILE_MASKED || state == UNIT_FILE_MASKED_RUNTIME) {
1628 log_error("Failed to enable unit: Unit %s is masked", *i);
1632 r = install_info_add_auto(&c, *i);
1637 /* This will return the number of symlink rules that were
1638 supposed to be created, not the ones actually created. This is
1639 useful to determine whether the passed files had any
1640 installation data at all. */
1642 return install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes);
1645 int unit_file_disable(
1646 UnitFileScope scope,
1648 const char *root_dir,
1650 UnitFileChange **changes,
1651 unsigned *n_changes) {
1653 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1654 _cleanup_(install_context_done) InstallContext c = {};
1656 _cleanup_free_ char *config_path = NULL;
1657 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
1661 assert(scope < _UNIT_FILE_SCOPE_MAX);
1663 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1667 r = get_config_path(scope, runtime, root_dir, &config_path);
1671 STRV_FOREACH(i, files) {
1672 r = install_info_add_auto(&c, *i);
1677 r = install_context_mark_for_removal(&c, &paths, &remove_symlinks_to, config_path, root_dir);
1679 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
1686 int unit_file_reenable(
1687 UnitFileScope scope,
1689 const char *root_dir,
1692 UnitFileChange **changes,
1693 unsigned *n_changes) {
1696 r = unit_file_disable(scope, runtime, root_dir, files,
1697 changes, n_changes);
1701 return unit_file_enable(scope, runtime, root_dir, files, force,
1702 changes, n_changes);
1705 int unit_file_set_default(
1706 UnitFileScope scope,
1707 const char *root_dir,
1710 UnitFileChange **changes,
1711 unsigned *n_changes) {
1713 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1714 _cleanup_(install_context_done) InstallContext c = {};
1715 _cleanup_free_ char *config_path = NULL;
1718 InstallInfo *i = NULL;
1721 assert(scope < _UNIT_FILE_SCOPE_MAX);
1724 if (unit_name_to_type(file) != UNIT_TARGET)
1727 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1731 r = get_config_path(scope, false, root_dir, &config_path);
1735 r = install_info_add_auto(&c, file);
1739 assert_se(i = ordered_hashmap_first(c.will_install));
1741 r = unit_file_search(&c, i, &paths, root_dir, false, true);
1745 path = strappenda(config_path, "/" SPECIAL_DEFAULT_TARGET);
1747 r = create_symlink(i->path, path, force, changes, n_changes);
1754 int unit_file_get_default(
1755 UnitFileScope scope,
1756 const char *root_dir,
1759 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1764 assert(scope < _UNIT_FILE_SCOPE_MAX);
1767 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1771 STRV_FOREACH(p, paths.unit_path) {
1772 _cleanup_free_ char *path = NULL, *tmp = NULL;
1775 path = path_join(root_dir, *p, SPECIAL_DEFAULT_TARGET);
1779 r = readlink_malloc(path, &tmp);
1782 else if (r == -EINVAL)
1784 n = strdup(SPECIAL_DEFAULT_TARGET);
1788 n = strdup(basename(tmp));
1800 UnitFileState unit_file_get_state(
1801 UnitFileScope scope,
1802 const char *root_dir,
1805 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1806 UnitFileState state = _UNIT_FILE_STATE_INVALID;
1808 _cleanup_free_ char *path = NULL;
1812 assert(scope < _UNIT_FILE_SCOPE_MAX);
1815 if (root_dir && scope != UNIT_FILE_SYSTEM)
1818 if (!unit_name_is_valid(name, TEMPLATE_VALID))
1821 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1825 STRV_FOREACH(i, paths.unit_path) {
1832 path = path_join(root_dir, *i, name);
1837 partial = path + strlen(root_dir);
1842 * Search for a unit file in our default paths, to
1843 * be sure, that there are no broken symlinks.
1845 if (lstat(path, &st) < 0) {
1847 if (errno != ENOENT)
1850 if (!unit_name_is_instance(name))
1853 if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode))
1856 r = null_or_empty_path(path);
1857 if (r < 0 && r != -ENOENT)
1860 state = path_startswith(*i, "/run") ?
1861 UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
1866 r = find_symlinks_in_scope(scope, root_dir, name, &state);
1872 r = unit_file_can_install(&paths, root_dir, partial, true);
1873 if (r < 0 && errno != ENOENT)
1876 return UNIT_FILE_DISABLED;
1878 return UNIT_FILE_STATIC;
1881 return r < 0 ? r : state;
1884 int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name) {
1885 _cleanup_strv_free_ char **files = NULL;
1890 assert(scope < _UNIT_FILE_SCOPE_MAX);
1893 if (scope == UNIT_FILE_SYSTEM)
1894 r = conf_files_list(&files, ".preset", root_dir,
1895 "/etc/systemd/system-preset",
1896 "/usr/local/lib/systemd/system-preset",
1897 "/usr/lib/systemd/system-preset",
1898 #ifdef HAVE_SPLIT_USR
1899 "/lib/systemd/system-preset",
1902 else if (scope == UNIT_FILE_GLOBAL)
1903 r = conf_files_list(&files, ".preset", root_dir,
1904 "/etc/systemd/user-preset",
1905 "/usr/local/lib/systemd/user-preset",
1906 "/usr/lib/systemd/user-preset",
1914 STRV_FOREACH(p, files) {
1915 _cleanup_fclose_ FILE *f;
1917 f = fopen(*p, "re");
1919 if (errno == ENOENT)
1926 char line[LINE_MAX], *l;
1928 if (!fgets(line, sizeof(line), f))
1935 if (strchr(COMMENTS "\n", *l))
1938 if (first_word(l, "enable")) {
1940 l += strspn(l, WHITESPACE);
1942 if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
1943 log_debug("Preset file says enable %s.", name);
1947 } else if (first_word(l, "disable")) {
1949 l += strspn(l, WHITESPACE);
1951 if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
1952 log_debug("Preset file says disable %s.", name);
1957 log_debug("Couldn't parse line '%s'", l);
1961 /* Default is "enable" */
1962 log_debug("Preset file doesn't say anything about %s, enabling.", name);
1966 int unit_file_preset(
1967 UnitFileScope scope,
1969 const char *root_dir,
1971 UnitFilePresetMode mode,
1973 UnitFileChange **changes,
1974 unsigned *n_changes) {
1976 _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
1977 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1978 _cleanup_free_ char *config_path = NULL;
1983 assert(scope < _UNIT_FILE_SCOPE_MAX);
1984 assert(mode < _UNIT_FILE_PRESET_MAX);
1986 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1990 r = get_config_path(scope, runtime, root_dir, &config_path);
1994 STRV_FOREACH(i, files) {
1996 if (!unit_name_is_valid(*i, TEMPLATE_VALID))
1999 r = unit_file_query_preset(scope, root_dir, *i);
2003 if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
2004 r = install_info_add_auto(&plus, *i);
2005 else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
2006 r = install_info_add_auto(&minus, *i);
2015 if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
2016 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
2018 r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
2020 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
2025 if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
2026 /* Returns number of symlinks that where supposed to be installed. */
2027 q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
2035 int unit_file_preset_all(
2036 UnitFileScope scope,
2038 const char *root_dir,
2039 UnitFilePresetMode mode,
2041 UnitFileChange **changes,
2042 unsigned *n_changes) {
2044 _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
2045 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2046 _cleanup_free_ char *config_path = NULL;
2051 assert(scope < _UNIT_FILE_SCOPE_MAX);
2052 assert(mode < _UNIT_FILE_PRESET_MAX);
2054 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
2058 r = get_config_path(scope, runtime, root_dir, &config_path);
2062 STRV_FOREACH(i, paths.unit_path) {
2063 _cleanup_closedir_ DIR *d = NULL;
2064 _cleanup_free_ char *units_dir;
2066 units_dir = path_join(root_dir, *i, NULL);
2070 d = opendir(units_dir);
2072 if (errno == ENOENT)
2083 if (!de && errno != 0)
2089 if (ignore_file(de->d_name))
2092 if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
2095 dirent_ensure_type(d, de);
2097 if (de->d_type != DT_REG)
2100 r = unit_file_query_preset(scope, root_dir, de->d_name);
2104 if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
2105 r = install_info_add_auto(&plus, de->d_name);
2106 else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
2107 r = install_info_add_auto(&minus, de->d_name);
2117 if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
2118 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
2120 r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
2122 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, NULL);
2127 if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
2128 q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
2136 static void unit_file_list_free_one(UnitFileList *f) {
2144 DEFINE_TRIVIAL_CLEANUP_FUNC(UnitFileList*, unit_file_list_free_one);
2146 int unit_file_get_list(
2147 UnitFileScope scope,
2148 const char *root_dir,
2151 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2156 assert(scope < _UNIT_FILE_SCOPE_MAX);
2159 if (root_dir && scope != UNIT_FILE_SYSTEM)
2163 r = access(root_dir, F_OK);
2168 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
2172 STRV_FOREACH(i, paths.unit_path) {
2173 _cleanup_closedir_ DIR *d = NULL;
2174 _cleanup_free_ char *units_dir;
2176 units_dir = path_join(root_dir, *i, NULL);
2180 d = opendir(units_dir);
2182 if (errno == ENOENT)
2189 _cleanup_(unit_file_list_free_onep) UnitFileList *f = NULL;
2191 _cleanup_free_ char *path = NULL;
2195 if (!de && errno != 0)
2201 if (ignore_file(de->d_name))
2204 if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
2207 if (hashmap_get(h, de->d_name))
2210 dirent_ensure_type(d, de);
2212 if (!IN_SET(de->d_type, DT_LNK, DT_REG))
2215 f = new0(UnitFileList, 1);
2219 f->path = path_make_absolute(de->d_name, units_dir);
2223 r = null_or_empty_path(f->path);
2224 if (r < 0 && r != -ENOENT)
2228 path_startswith(*i, "/run") ?
2229 UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
2233 r = find_symlinks_in_scope(scope, root_dir, de->d_name, &f->state);
2237 f->state = UNIT_FILE_ENABLED;
2241 path = path_make_absolute(de->d_name, *i);
2245 r = unit_file_can_install(&paths, root_dir, path, true);
2246 if (r == -EINVAL || /* Invalid setting? */
2247 r == -EBADMSG || /* Invalid format? */
2248 r == -ENOENT /* Included file not found? */)
2249 f->state = UNIT_FILE_INVALID;
2253 f->state = UNIT_FILE_DISABLED;
2255 f->state = UNIT_FILE_STATIC;
2258 r = hashmap_put(h, basename(f->path), f);
2261 f = NULL; /* prevent cleanup */
2268 static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
2269 [UNIT_FILE_ENABLED] = "enabled",
2270 [UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtime",
2271 [UNIT_FILE_LINKED] = "linked",
2272 [UNIT_FILE_LINKED_RUNTIME] = "linked-runtime",
2273 [UNIT_FILE_MASKED] = "masked",
2274 [UNIT_FILE_MASKED_RUNTIME] = "masked-runtime",
2275 [UNIT_FILE_STATIC] = "static",
2276 [UNIT_FILE_DISABLED] = "disabled",
2277 [UNIT_FILE_INVALID] = "invalid",
2280 DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);
2282 static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = {
2283 [UNIT_FILE_SYMLINK] = "symlink",
2284 [UNIT_FILE_UNLINK] = "unlink",
2287 DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
2289 static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MAX] = {
2290 [UNIT_FILE_PRESET_FULL] = "full",
2291 [UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
2292 [UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
2295 DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode, UnitFilePresetMode);