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 "install-printf.h"
43 OrderedHashmap *will_install;
44 OrderedHashmap *have_installed;
47 static int in_search_path(const char *path, char **search) {
48 _cleanup_free_ char *parent = NULL;
53 r = path_get_parent(path, &parent);
57 return strv_contains(search, parent);
60 static int get_config_path(UnitFileScope scope, bool runtime, const char *root_dir, char **ret) {
65 assert(scope < _UNIT_FILE_SCOPE_MAX);
70 case UNIT_FILE_SYSTEM:
73 p = path_join(root_dir, "/run/systemd/system", NULL);
75 p = path_join(root_dir, SYSTEM_CONFIG_UNIT_PATH, NULL);
78 case UNIT_FILE_GLOBAL:
84 p = strdup("/run/systemd/user");
86 p = strdup(USER_CONFIG_UNIT_PATH);
95 r = user_runtime_dir(&p);
97 r = user_config_home(&p);
100 return r < 0 ? r : -ENOENT;
105 assert_not_reached("Bad scope");
115 static int add_file_change(
116 UnitFileChange **changes,
118 UnitFileChangeType type,
120 const char *source) {
126 assert(!changes == !n_changes);
131 c = realloc(*changes, (*n_changes + 1) * sizeof(UnitFileChange));
139 c[i].path = strdup(path);
143 path_kill_slashes(c[i].path);
146 c[i].source = strdup(source);
152 path_kill_slashes(c[i].path);
160 static int mark_symlink_for_removal(
161 Set **remove_symlinks_to,
169 r = set_ensure_allocated(remove_symlinks_to, &string_hash_ops);
177 path_kill_slashes(n);
179 r = set_consume(*remove_symlinks_to, n);
181 return r == -EEXIST ? 0 : r;
186 static int remove_marked_symlinks_fd(
187 Set *remove_symlinks_to,
190 const char *config_path,
192 UnitFileChange **changes,
194 char** instance_whitelist) {
196 _cleanup_closedir_ DIR *d = NULL;
199 assert(remove_symlinks_to);
218 if (!de && errno != 0) {
226 if (hidden_file(de->d_name))
229 dirent_ensure_type(d, de);
231 if (de->d_type == DT_DIR) {
233 _cleanup_free_ char *p = NULL;
235 nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
245 p = path_make_absolute(de->d_name, path);
251 /* This will close nfd, regardless whether it succeeds or not */
252 q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, deleted, changes, n_changes, instance_whitelist);
256 } else if (de->d_type == DT_LNK) {
257 _cleanup_free_ char *p = NULL, *dest = NULL;
261 if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
264 if (unit_name_is_instance(de->d_name) &&
265 instance_whitelist &&
266 !strv_contains(instance_whitelist, de->d_name)) {
268 _cleanup_free_ char *w;
270 /* OK, the file is not listed directly
271 * in the whitelist, so let's check if
272 * the template of it might be
275 w = unit_name_template(de->d_name);
279 if (!strv_contains(instance_whitelist, w))
283 p = path_make_absolute(de->d_name, path);
287 q = readlink_and_canonicalize(p, &dest);
298 set_get(remove_symlinks_to, dest) ||
299 set_get(remove_symlinks_to, basename(dest));
304 if (unlink(p) < 0 && errno != ENOENT) {
310 path_kill_slashes(p);
311 rmdir_parents(p, config_path);
312 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, p, NULL);
314 if (!set_get(remove_symlinks_to, p)) {
316 q = mark_symlink_for_removal(&remove_symlinks_to, p);
329 static int remove_marked_symlinks(
330 Set *remove_symlinks_to,
331 const char *config_path,
332 UnitFileChange **changes,
334 char** instance_whitelist) {
336 _cleanup_close_ int fd = -1;
342 if (set_size(remove_symlinks_to) <= 0)
345 fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
353 cfd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
359 /* This takes possession of cfd and closes it */
360 q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, &deleted, changes, n_changes, instance_whitelist);
368 static int find_symlinks_fd(
372 const char *config_path,
373 bool *same_name_link) {
376 _cleanup_closedir_ DIR *d = NULL;
382 assert(same_name_link);
395 if (!de && errno != 0)
401 if (hidden_file(de->d_name))
404 dirent_ensure_type(d, de);
406 if (de->d_type == DT_DIR) {
408 _cleanup_free_ char *p = NULL;
410 nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
420 p = path_make_absolute(de->d_name, path);
426 /* This will close nfd, regardless whether it succeeds or not */
427 q = find_symlinks_fd(name, nfd, p, config_path, same_name_link);
433 } else if (de->d_type == DT_LNK) {
434 _cleanup_free_ char *p = NULL, *dest = NULL;
435 bool found_path, found_dest, b = false;
438 /* Acquire symlink name */
439 p = path_make_absolute(de->d_name, path);
443 /* Acquire symlink destination */
444 q = readlink_and_canonicalize(p, &dest);
454 /* Check if the symlink itself matches what we
456 if (path_is_absolute(name))
457 found_path = path_equal(p, name);
459 found_path = streq(de->d_name, name);
461 /* Check if what the symlink points to
462 * matches what we are looking for */
463 if (path_is_absolute(name))
464 found_dest = path_equal(dest, name);
466 found_dest = streq(basename(dest), name);
468 if (found_path && found_dest) {
469 _cleanup_free_ char *t = NULL;
471 /* Filter out same name links in the main
473 t = path_make_absolute(name, config_path);
477 b = path_equal(t, p);
481 *same_name_link = true;
482 else if (found_path || found_dest)
488 static int find_symlinks(
490 const char *config_path,
491 bool *same_name_link) {
497 assert(same_name_link);
499 fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
506 /* This takes possession of fd and closes it */
507 return find_symlinks_fd(name, fd, config_path, config_path, same_name_link);
510 static int find_symlinks_in_scope(
512 const char *root_dir,
514 UnitFileState *state) {
517 _cleanup_free_ char *path = NULL;
518 bool same_name_link_runtime = false, same_name_link = false;
521 assert(scope < _UNIT_FILE_SCOPE_MAX);
524 /* First look in runtime config path */
525 r = get_config_path(scope, true, root_dir, &path);
529 r = find_symlinks(name, path, &same_name_link_runtime);
533 *state = UNIT_FILE_ENABLED_RUNTIME;
537 /* Then look in the normal config path */
538 r = get_config_path(scope, false, root_dir, &path);
542 r = find_symlinks(name, path, &same_name_link);
546 *state = UNIT_FILE_ENABLED;
550 /* Hmm, we didn't find it, but maybe we found the same name
552 if (same_name_link_runtime) {
553 *state = UNIT_FILE_LINKED_RUNTIME;
555 } else if (same_name_link) {
556 *state = UNIT_FILE_LINKED;
566 const char *root_dir,
569 UnitFileChange **changes,
570 unsigned *n_changes) {
573 _cleanup_free_ char *prefix = NULL;
577 assert(scope < _UNIT_FILE_SCOPE_MAX);
579 r = get_config_path(scope, runtime, root_dir, &prefix);
583 STRV_FOREACH(i, files) {
584 _cleanup_free_ char *path = NULL;
586 if (!unit_name_is_valid(*i, TEMPLATE_VALID)) {
592 path = path_make_absolute(*i, prefix);
598 if (symlink("/dev/null", path) >= 0) {
599 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null");
603 if (errno == EEXIST) {
605 if (null_or_empty_path(path) > 0)
609 if (symlink_atomic("/dev/null", path) >= 0) {
610 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
611 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null");
627 int unit_file_unmask(
630 const char *root_dir,
632 UnitFileChange **changes,
633 unsigned *n_changes) {
635 char **i, *config_path = NULL;
637 Set *remove_symlinks_to = NULL;
640 assert(scope < _UNIT_FILE_SCOPE_MAX);
642 r = get_config_path(scope, runtime, root_dir, &config_path);
646 STRV_FOREACH(i, files) {
647 _cleanup_free_ char *path = NULL;
649 if (!unit_name_is_valid(*i, TEMPLATE_VALID)) {
655 path = path_make_absolute(*i, config_path);
661 q = null_or_empty_path(path);
663 if (unlink(path) < 0)
666 q = mark_symlink_for_removal(&remove_symlinks_to, path);
667 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
671 if (q != -ENOENT && r == 0)
677 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
681 set_free_free(remove_symlinks_to);
690 const char *root_dir,
693 UnitFileChange **changes,
694 unsigned *n_changes) {
696 _cleanup_lookup_paths_free_ LookupPaths paths = {};
698 _cleanup_free_ char *config_path = NULL;
702 assert(scope < _UNIT_FILE_SCOPE_MAX);
704 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
708 r = get_config_path(scope, runtime, root_dir, &config_path);
712 STRV_FOREACH(i, files) {
713 _cleanup_free_ char *path = NULL;
719 if (!path_is_absolute(*i) ||
720 !unit_name_is_valid(fn, TEMPLATE_VALID)) {
726 if (lstat(*i, &st) < 0) {
732 if (!S_ISREG(st.st_mode)) {
737 q = in_search_path(*i, paths.unit_path);
744 path = path_make_absolute(fn, config_path);
748 if (symlink(*i, path) >= 0) {
749 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, *i);
753 if (errno == EEXIST) {
754 _cleanup_free_ char *dest = NULL;
756 q = readlink_and_make_absolute(path, &dest);
757 if (q < 0 && errno != ENOENT) {
763 if (q >= 0 && path_equal(dest, *i))
767 if (symlink_atomic(*i, path) >= 0) {
768 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
769 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, *i);
785 void unit_file_list_free(Hashmap *h) {
788 while ((i = hashmap_steal_first(h))) {
796 void unit_file_changes_free(UnitFileChange *changes, unsigned n_changes) {
799 assert(changes || n_changes == 0);
804 for (i = 0; i < n_changes; i++) {
805 free(changes[i].path);
806 free(changes[i].source);
812 static void install_info_free(InstallInfo *i) {
817 strv_free(i->aliases);
818 strv_free(i->wanted_by);
819 strv_free(i->required_by);
821 free(i->default_instance);
825 static void install_info_hashmap_free(OrderedHashmap *m) {
831 while ((i = ordered_hashmap_steal_first(m)))
832 install_info_free(i);
834 ordered_hashmap_free(m);
837 static void install_context_done(InstallContext *c) {
840 install_info_hashmap_free(c->will_install);
841 install_info_hashmap_free(c->have_installed);
843 c->will_install = c->have_installed = NULL;
846 static int install_info_add(
850 InstallInfo *i = NULL;
854 assert(name || path);
857 name = basename(path);
859 if (!unit_name_is_valid(name, TEMPLATE_VALID))
862 if (ordered_hashmap_get(c->have_installed, name) ||
863 ordered_hashmap_get(c->will_install, name))
866 r = ordered_hashmap_ensure_allocated(&c->will_install, &string_hash_ops);
870 i = new0(InstallInfo, 1);
874 i->name = strdup(name);
881 i->path = strdup(path);
888 r = ordered_hashmap_put(c->will_install, i->name, i);
896 install_info_free(i);
901 static int install_info_add_auto(
903 const char *name_or_path) {
906 assert(name_or_path);
908 if (path_is_absolute(name_or_path))
909 return install_info_add(c, NULL, name_or_path);
911 return install_info_add(c, name_or_path, NULL);
914 static int config_parse_also(
916 const char *filename,
919 unsigned section_line,
927 const char *word, *state;
928 InstallContext *c = data;
929 InstallInfo *i = userdata;
935 FOREACH_WORD_QUOTED(word, l, rvalue, state) {
936 _cleanup_free_ char *n;
939 n = strndup(word, l);
943 r = install_info_add(c, n, NULL);
947 r = strv_extend(&i->also, n);
952 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
953 "Trailing garbage, ignoring.");
958 static int config_parse_user(
960 const char *filename,
963 unsigned section_line,
970 InstallInfo *i = data;
978 r = install_full_printf(i, rvalue, &printed);
988 static int config_parse_default_instance(
990 const char *filename,
993 unsigned section_line,
1000 InstallInfo *i = data;
1008 r = install_full_printf(i, rvalue, &printed);
1012 if (!unit_instance_is_valid(printed)) {
1017 free(i->default_instance);
1018 i->default_instance = printed;
1023 static int unit_file_load(
1027 const char *root_dir,
1032 const ConfigTableItem items[] = {
1033 { "Install", "Alias", config_parse_strv, 0, &info->aliases },
1034 { "Install", "WantedBy", config_parse_strv, 0, &info->wanted_by },
1035 { "Install", "RequiredBy", config_parse_strv, 0, &info->required_by },
1036 { "Install", "DefaultInstance", config_parse_default_instance, 0, info },
1037 { "Install", "Also", config_parse_also, 0, c },
1038 { "Exec", "User", config_parse_user, 0, info },
1042 _cleanup_fclose_ FILE *f = NULL;
1049 if (!isempty(root_dir))
1050 path = strjoina(root_dir, "/", path);
1053 r = access(path, F_OK) ? -errno : 0;
1057 fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|(allow_symlink ? 0 : O_NOFOLLOW));
1061 f = fdopen(fd, "re");
1067 r = config_parse(NULL, path, f,
1069 config_item_table_lookup, items,
1070 true, true, false, info);
1075 *also = !strv_isempty(info->also);
1078 (int) strv_length(info->aliases) +
1079 (int) strv_length(info->wanted_by) +
1080 (int) strv_length(info->required_by);
1083 static int unit_file_search(
1086 const LookupPaths *paths,
1087 const char *root_dir,
1100 return unit_file_load(c, info, info->path, root_dir, allow_symlink, load, also);
1104 STRV_FOREACH(p, paths->unit_path) {
1105 _cleanup_free_ char *path = NULL;
1107 path = strjoin(*p, "/", info->name, NULL);
1111 r = unit_file_load(c, info, path, root_dir, allow_symlink, load, also);
1117 if (r != -ENOENT && r != -ELOOP)
1121 if (unit_name_is_instance(info->name)) {
1123 /* Unit file doesn't exist, however instance
1124 * enablement was requested. We will check if it is
1125 * possible to load template unit file. */
1127 _cleanup_free_ char *template = NULL;
1129 template = unit_name_template(info->name);
1133 STRV_FOREACH(p, paths->unit_path) {
1134 _cleanup_free_ char *path = NULL;
1136 path = strjoin(*p, "/", template, NULL);
1140 r = unit_file_load(c, info, path, root_dir, allow_symlink, load, also);
1146 if (r != -ENOENT && r != -ELOOP)
1154 static int unit_file_can_install(
1155 const LookupPaths *paths,
1156 const char *root_dir,
1161 _cleanup_(install_context_done) InstallContext c = {};
1168 r = install_info_add_auto(&c, name);
1172 assert_se(i = ordered_hashmap_first(c.will_install));
1174 r = unit_file_search(&c, i, paths, root_dir, allow_symlink, true, also);
1178 (int) strv_length(i->aliases) +
1179 (int) strv_length(i->wanted_by) +
1180 (int) strv_length(i->required_by);
1185 static int create_symlink(
1186 const char *old_path,
1187 const char *new_path,
1189 UnitFileChange **changes,
1190 unsigned *n_changes) {
1192 _cleanup_free_ char *dest = NULL;
1198 mkdir_parents_label(new_path, 0755);
1200 if (symlink(old_path, new_path) >= 0) {
1201 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
1205 if (errno != EEXIST)
1208 r = readlink_and_make_absolute(new_path, &dest);
1212 if (path_equal(dest, old_path))
1218 r = symlink_atomic(old_path, new_path);
1222 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL);
1223 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
1228 static int install_info_symlink_alias(
1230 const char *config_path,
1232 UnitFileChange **changes,
1233 unsigned *n_changes) {
1239 assert(config_path);
1241 STRV_FOREACH(s, i->aliases) {
1242 _cleanup_free_ char *alias_path = NULL, *dst = NULL;
1244 q = install_full_printf(i, *s, &dst);
1248 alias_path = path_make_absolute(dst, config_path);
1252 q = create_symlink(i->path, alias_path, force, changes, n_changes);
1260 static int install_info_symlink_wants(
1262 const char *config_path,
1266 UnitFileChange **changes,
1267 unsigned *n_changes) {
1269 _cleanup_free_ char *buf = NULL;
1275 assert(config_path);
1277 if (unit_name_is_template(i->name)) {
1279 /* Don't install any symlink if there's no default
1280 * instance configured */
1282 if (!i->default_instance)
1285 buf = unit_name_replace_instance(i->name, i->default_instance);
1293 STRV_FOREACH(s, list) {
1294 _cleanup_free_ char *path = NULL, *dst = NULL;
1296 q = install_full_printf(i, *s, &dst);
1300 if (!unit_name_is_valid(dst, TEMPLATE_VALID)) {
1305 path = strjoin(config_path, "/", dst, suffix, n, NULL);
1309 q = create_symlink(i->path, path, force, changes, n_changes);
1317 static int install_info_symlink_link(
1319 const LookupPaths *paths,
1320 const char *config_path,
1321 const char *root_dir,
1323 UnitFileChange **changes,
1324 unsigned *n_changes) {
1326 _cleanup_free_ char *path = NULL;
1331 assert(config_path);
1334 r = in_search_path(i->path, paths->unit_path);
1338 path = strjoin(config_path, "/", i->name, NULL);
1342 return create_symlink(i->path, path, force, changes, n_changes);
1345 static int install_info_apply(
1347 const LookupPaths *paths,
1348 const char *config_path,
1349 const char *root_dir,
1351 UnitFileChange **changes,
1352 unsigned *n_changes) {
1358 assert(config_path);
1360 r = install_info_symlink_alias(i, config_path, force, changes, n_changes);
1362 q = install_info_symlink_wants(i, config_path, i->wanted_by, ".wants/", force, changes, n_changes);
1366 q = install_info_symlink_wants(i, config_path, i->required_by, ".requires/", force, changes, n_changes);
1370 q = install_info_symlink_link(i, paths, config_path, root_dir, force, changes, n_changes);
1377 static int install_context_apply(
1379 const LookupPaths *paths,
1380 const char *config_path,
1381 const char *root_dir,
1383 UnitFileChange **changes,
1384 unsigned *n_changes) {
1391 assert(config_path);
1393 if (!ordered_hashmap_isempty(c->will_install)) {
1394 r = ordered_hashmap_ensure_allocated(&c->have_installed, &string_hash_ops);
1398 r = ordered_hashmap_reserve(c->have_installed, ordered_hashmap_size(c->will_install));
1404 while ((i = ordered_hashmap_first(c->will_install))) {
1405 assert_se(ordered_hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
1407 q = unit_file_search(c, i, paths, root_dir, false, true, NULL);
1416 q = install_info_apply(i, paths, config_path, root_dir, force, changes, n_changes);
1417 if (r >= 0 && q < 0)
1424 static int install_context_mark_for_removal(
1426 const LookupPaths *paths,
1427 Set **remove_symlinks_to,
1428 const char *config_path,
1429 const char *root_dir) {
1436 assert(config_path);
1438 /* Marks all items for removal */
1440 if (!ordered_hashmap_isempty(c->will_install)) {
1441 r = ordered_hashmap_ensure_allocated(&c->have_installed, &string_hash_ops);
1445 r = ordered_hashmap_reserve(c->have_installed, ordered_hashmap_size(c->will_install));
1451 while ((i = ordered_hashmap_first(c->will_install))) {
1452 assert_se(ordered_hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
1454 q = unit_file_search(c, i, paths, root_dir, false, true, NULL);
1465 if (unit_name_is_instance(i->name)) {
1469 unit_file = basename(i->path);
1471 if (unit_name_is_instance(unit_file))
1472 /* unit file named as instance exists, thus all symlinks
1473 * pointing to it will be removed */
1474 q = mark_symlink_for_removal(remove_symlinks_to, i->name);
1476 /* does not exist, thus we will mark for removal symlinks
1477 * to template unit file */
1478 q = mark_symlink_for_removal(remove_symlinks_to, unit_file);
1480 /* If i->path is not set, it means that we didn't actually find
1481 * the unit file. But we can still remove symlinks to the
1482 * nonexistent template. */
1483 unit_file = unit_name_template(i->name);
1487 q = mark_symlink_for_removal(remove_symlinks_to, unit_file);
1491 q = mark_symlink_for_removal(remove_symlinks_to, i->name);
1493 if (r >= 0 && q < 0)
1500 int unit_file_add_dependency(
1501 UnitFileScope scope,
1503 const char *root_dir,
1508 UnitFileChange **changes,
1509 unsigned *n_changes) {
1511 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1512 _cleanup_(install_context_done) InstallContext c = {};
1513 _cleanup_free_ char *config_path = NULL;
1519 assert(scope < _UNIT_FILE_SCOPE_MAX);
1521 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1525 r = get_config_path(scope, runtime, root_dir, &config_path);
1529 STRV_FOREACH(i, files) {
1530 UnitFileState state;
1532 state = unit_file_get_state(scope, root_dir, *i);
1534 return log_error_errno(state, "Failed to get unit file state for %s: %m", *i);
1536 if (state == UNIT_FILE_MASKED || state == UNIT_FILE_MASKED_RUNTIME) {
1537 log_error("Failed to enable unit: Unit %s is masked", *i);
1541 r = install_info_add_auto(&c, *i);
1546 if (!ordered_hashmap_isempty(c.will_install)) {
1547 r = ordered_hashmap_ensure_allocated(&c.have_installed, &string_hash_ops);
1551 r = ordered_hashmap_reserve(c.have_installed, ordered_hashmap_size(c.will_install));
1556 while ((info = ordered_hashmap_first(c.will_install))) {
1557 assert_se(ordered_hashmap_move_one(c.have_installed, c.will_install, info->name) == 0);
1559 r = unit_file_search(&c, info, &paths, root_dir, false, false, NULL);
1563 if (dep == UNIT_WANTS)
1564 r = strv_extend(&info->wanted_by, target);
1565 else if (dep == UNIT_REQUIRES)
1566 r = strv_extend(&info->required_by, target);
1573 r = install_info_apply(info, &paths, config_path, root_dir, force, changes, n_changes);
1581 int unit_file_enable(
1582 UnitFileScope scope,
1584 const char *root_dir,
1587 UnitFileChange **changes,
1588 unsigned *n_changes) {
1590 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1591 _cleanup_(install_context_done) InstallContext c = {};
1593 _cleanup_free_ char *config_path = NULL;
1597 assert(scope < _UNIT_FILE_SCOPE_MAX);
1599 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1603 r = get_config_path(scope, runtime, root_dir, &config_path);
1607 STRV_FOREACH(i, files) {
1608 UnitFileState state;
1610 /* We only want to know if this unit is masked, so we ignore
1611 * errors from unit_file_get_state, deferring other checks.
1612 * This allows templated units to be enabled on the fly. */
1613 state = unit_file_get_state(scope, root_dir, *i);
1614 if (state == UNIT_FILE_MASKED || state == UNIT_FILE_MASKED_RUNTIME) {
1615 log_error("Failed to enable unit: Unit %s is masked", *i);
1619 r = install_info_add_auto(&c, *i);
1624 /* This will return the number of symlink rules that were
1625 supposed to be created, not the ones actually created. This is
1626 useful to determine whether the passed files had any
1627 installation data at all. */
1629 return install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes);
1632 int unit_file_disable(
1633 UnitFileScope scope,
1635 const char *root_dir,
1637 UnitFileChange **changes,
1638 unsigned *n_changes) {
1640 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1641 _cleanup_(install_context_done) InstallContext c = {};
1643 _cleanup_free_ char *config_path = NULL;
1644 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
1648 assert(scope < _UNIT_FILE_SCOPE_MAX);
1650 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1654 r = get_config_path(scope, runtime, root_dir, &config_path);
1658 STRV_FOREACH(i, files) {
1659 r = install_info_add_auto(&c, *i);
1664 r = install_context_mark_for_removal(&c, &paths, &remove_symlinks_to, config_path, root_dir);
1666 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
1673 int unit_file_reenable(
1674 UnitFileScope scope,
1676 const char *root_dir,
1679 UnitFileChange **changes,
1680 unsigned *n_changes) {
1683 r = unit_file_disable(scope, runtime, root_dir, files,
1684 changes, n_changes);
1688 return unit_file_enable(scope, runtime, root_dir, files, force,
1689 changes, n_changes);
1692 int unit_file_set_default(
1693 UnitFileScope scope,
1694 const char *root_dir,
1697 UnitFileChange **changes,
1698 unsigned *n_changes) {
1700 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1701 _cleanup_(install_context_done) InstallContext c = {};
1702 _cleanup_free_ char *config_path = NULL;
1705 InstallInfo *i = NULL;
1708 assert(scope < _UNIT_FILE_SCOPE_MAX);
1711 if (unit_name_to_type(file) != UNIT_TARGET)
1714 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1718 r = get_config_path(scope, false, root_dir, &config_path);
1722 r = install_info_add_auto(&c, file);
1726 assert_se(i = ordered_hashmap_first(c.will_install));
1728 r = unit_file_search(&c, i, &paths, root_dir, false, true, NULL);
1732 path = strjoina(config_path, "/" SPECIAL_DEFAULT_TARGET);
1734 r = create_symlink(i->path, path, force, changes, n_changes);
1741 int unit_file_get_default(
1742 UnitFileScope scope,
1743 const char *root_dir,
1746 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1751 assert(scope < _UNIT_FILE_SCOPE_MAX);
1754 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1758 STRV_FOREACH(p, paths.unit_path) {
1759 _cleanup_free_ char *path = NULL, *tmp = NULL;
1762 path = path_join(root_dir, *p, SPECIAL_DEFAULT_TARGET);
1766 r = readlink_malloc(path, &tmp);
1769 else if (r == -EINVAL)
1771 n = strdup(SPECIAL_DEFAULT_TARGET);
1775 n = strdup(basename(tmp));
1787 UnitFileState unit_file_lookup_state(
1788 UnitFileScope scope,
1789 const char *root_dir,
1790 const LookupPaths *paths,
1793 UnitFileState state = _UNIT_FILE_STATE_INVALID;
1795 _cleanup_free_ char *path = NULL;
1800 if (!unit_name_is_valid(name, TEMPLATE_VALID))
1803 STRV_FOREACH(i, paths->unit_path) {
1809 path = path_join(root_dir, *i, name);
1814 partial = path + strlen(root_dir);
1819 * Search for a unit file in our default paths, to
1820 * be sure, that there are no broken symlinks.
1822 if (lstat(path, &st) < 0) {
1824 if (errno != ENOENT)
1827 if (!unit_name_is_instance(name))
1830 if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode))
1833 r = null_or_empty_path(path);
1834 if (r < 0 && r != -ENOENT)
1837 state = path_startswith(*i, "/run") ?
1838 UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
1843 r = find_symlinks_in_scope(scope, root_dir, name, &state);
1849 r = unit_file_can_install(paths, root_dir, partial, true, &also);
1850 if (r < 0 && errno != ENOENT)
1853 return UNIT_FILE_DISABLED;
1856 return UNIT_FILE_INDIRECT;
1857 return UNIT_FILE_STATIC;
1861 return r < 0 ? r : state;
1864 UnitFileState unit_file_get_state(
1865 UnitFileScope scope,
1866 const char *root_dir,
1869 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1873 assert(scope < _UNIT_FILE_SCOPE_MAX);
1876 if (root_dir && scope != UNIT_FILE_SYSTEM)
1879 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1883 return unit_file_lookup_state(scope, root_dir, &paths, name);
1886 int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name) {
1887 _cleanup_strv_free_ char **files = NULL;
1892 assert(scope < _UNIT_FILE_SCOPE_MAX);
1895 if (scope == UNIT_FILE_SYSTEM)
1896 r = conf_files_list(&files, ".preset", root_dir,
1897 "/etc/systemd/system-preset",
1898 "/usr/local/lib/systemd/system-preset",
1899 "/usr/lib/systemd/system-preset",
1900 #ifdef HAVE_SPLIT_USR
1901 "/lib/systemd/system-preset",
1904 else if (scope == UNIT_FILE_GLOBAL)
1905 r = conf_files_list(&files, ".preset", root_dir,
1906 "/etc/systemd/user-preset",
1907 "/usr/local/lib/systemd/user-preset",
1908 "/usr/lib/systemd/user-preset",
1916 STRV_FOREACH(p, files) {
1917 _cleanup_fclose_ FILE *f;
1919 f = fopen(*p, "re");
1921 if (errno == ENOENT)
1928 char line[LINE_MAX], *l;
1930 if (!fgets(line, sizeof(line), f))
1937 if (strchr(COMMENTS "\n", *l))
1940 if (first_word(l, "enable")) {
1942 l += strspn(l, WHITESPACE);
1944 if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
1945 log_debug("Preset file says enable %s.", name);
1949 } else if (first_word(l, "disable")) {
1951 l += strspn(l, WHITESPACE);
1953 if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
1954 log_debug("Preset file says disable %s.", name);
1959 log_debug("Couldn't parse line '%s'", l);
1963 /* Default is "enable" */
1964 log_debug("Preset file doesn't say anything about %s, enabling.", name);
1968 int unit_file_preset(
1969 UnitFileScope scope,
1971 const char *root_dir,
1973 UnitFilePresetMode mode,
1975 UnitFileChange **changes,
1976 unsigned *n_changes) {
1978 _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
1979 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1980 _cleanup_free_ char *config_path = NULL;
1985 assert(scope < _UNIT_FILE_SCOPE_MAX);
1986 assert(mode < _UNIT_FILE_PRESET_MAX);
1988 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1992 r = get_config_path(scope, runtime, root_dir, &config_path);
1996 STRV_FOREACH(i, files) {
1998 if (!unit_name_is_valid(*i, TEMPLATE_VALID))
2001 r = unit_file_query_preset(scope, root_dir, *i);
2005 if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
2006 r = install_info_add_auto(&plus, *i);
2007 else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
2008 r = install_info_add_auto(&minus, *i);
2017 if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
2018 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
2020 r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
2022 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
2027 if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
2028 /* Returns number of symlinks that where supposed to be installed. */
2029 q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
2037 int unit_file_preset_all(
2038 UnitFileScope scope,
2040 const char *root_dir,
2041 UnitFilePresetMode mode,
2043 UnitFileChange **changes,
2044 unsigned *n_changes) {
2046 _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
2047 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2048 _cleanup_free_ char *config_path = NULL;
2053 assert(scope < _UNIT_FILE_SCOPE_MAX);
2054 assert(mode < _UNIT_FILE_PRESET_MAX);
2056 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
2060 r = get_config_path(scope, runtime, root_dir, &config_path);
2064 STRV_FOREACH(i, paths.unit_path) {
2065 _cleanup_closedir_ DIR *d = NULL;
2066 _cleanup_free_ char *units_dir;
2068 units_dir = path_join(root_dir, *i, NULL);
2072 d = opendir(units_dir);
2074 if (errno == ENOENT)
2085 if (!de && errno != 0)
2091 if (hidden_file(de->d_name))
2094 if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
2097 dirent_ensure_type(d, de);
2099 if (de->d_type != DT_REG)
2102 r = unit_file_query_preset(scope, root_dir, de->d_name);
2106 if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
2107 r = install_info_add_auto(&plus, de->d_name);
2108 else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
2109 r = install_info_add_auto(&minus, de->d_name);
2119 if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
2120 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
2122 r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
2124 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, NULL);
2129 if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
2130 q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
2138 static void unit_file_list_free_one(UnitFileList *f) {
2146 DEFINE_TRIVIAL_CLEANUP_FUNC(UnitFileList*, unit_file_list_free_one);
2148 int unit_file_get_list(
2149 UnitFileScope scope,
2150 const char *root_dir,
2153 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2158 assert(scope < _UNIT_FILE_SCOPE_MAX);
2161 if (root_dir && scope != UNIT_FILE_SYSTEM)
2165 r = access(root_dir, F_OK);
2170 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
2174 STRV_FOREACH(i, paths.unit_path) {
2175 _cleanup_closedir_ DIR *d = NULL;
2176 _cleanup_free_ char *units_dir;
2178 units_dir = path_join(root_dir, *i, NULL);
2182 d = opendir(units_dir);
2184 if (errno == ENOENT)
2191 _cleanup_(unit_file_list_free_onep) UnitFileList *f = NULL;
2193 _cleanup_free_ char *path = NULL;
2197 if (!de && errno != 0)
2203 if (hidden_file(de->d_name))
2206 if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
2209 if (hashmap_get(h, de->d_name))
2212 dirent_ensure_type(d, de);
2214 if (!IN_SET(de->d_type, DT_LNK, DT_REG))
2217 f = new0(UnitFileList, 1);
2221 f->path = path_make_absolute(de->d_name, units_dir);
2225 r = null_or_empty_path(f->path);
2226 if (r < 0 && r != -ENOENT)
2230 path_startswith(*i, "/run") ?
2231 UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
2235 r = find_symlinks_in_scope(scope, root_dir, de->d_name, &f->state);
2239 f->state = UNIT_FILE_ENABLED;
2243 path = path_make_absolute(de->d_name, *i);
2247 r = unit_file_can_install(&paths, root_dir, path, true, NULL);
2248 if (r == -EINVAL || /* Invalid setting? */
2249 r == -EBADMSG || /* Invalid format? */
2250 r == -ENOENT /* Included file not found? */)
2251 f->state = UNIT_FILE_INVALID;
2255 f->state = UNIT_FILE_DISABLED;
2257 f->state = UNIT_FILE_STATIC;
2260 r = hashmap_put(h, basename(f->path), f);
2263 f = NULL; /* prevent cleanup */
2270 static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
2271 [UNIT_FILE_ENABLED] = "enabled",
2272 [UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtime",
2273 [UNIT_FILE_LINKED] = "linked",
2274 [UNIT_FILE_LINKED_RUNTIME] = "linked-runtime",
2275 [UNIT_FILE_MASKED] = "masked",
2276 [UNIT_FILE_MASKED_RUNTIME] = "masked-runtime",
2277 [UNIT_FILE_STATIC] = "static",
2278 [UNIT_FILE_DISABLED] = "disabled",
2279 [UNIT_FILE_INDIRECT] = "indirect",
2280 [UNIT_FILE_INVALID] = "invalid",
2283 DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);
2285 static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = {
2286 [UNIT_FILE_SYMLINK] = "symlink",
2287 [UNIT_FILE_UNLINK] = "unlink",
2290 DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
2292 static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MAX] = {
2293 [UNIT_FILE_PRESET_FULL] = "full",
2294 [UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
2295 [UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
2298 DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode, UnitFilePresetMode);