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 Hashmap *will_install;
45 Hashmap *have_installed;
48 #define _cleanup_install_context_done_ _cleanup_(install_context_done)
50 static int in_search_path(const char *path, char **search, const char *root_dir) {
51 _cleanup_free_ char *parent = NULL;
57 r = path_get_parent(path, &parent);
61 STRV_FOREACH(i, search) {
62 _cleanup_free_ char *buf = NULL;
66 buf = strjoin(root_dir, "/", *i, NULL);
74 if (path_equal(parent, p))
81 static int lookup_paths_init_from_scope(LookupPaths *paths,
83 const char *root_dir) {
86 assert(scope < _UNIT_FILE_SCOPE_MAX);
90 return lookup_paths_init(paths,
91 scope == UNIT_FILE_SYSTEM ? SYSTEMD_SYSTEM : SYSTEMD_USER,
92 scope == UNIT_FILE_USER,
97 static int get_config_path(UnitFileScope scope, bool runtime, const char *root_dir, char **ret) {
102 assert(scope < _UNIT_FILE_SCOPE_MAX);
107 case UNIT_FILE_SYSTEM:
109 if (root_dir && runtime)
110 asprintf(&p, "%s/run/systemd/system", root_dir);
112 p = strdup("/run/systemd/system");
114 asprintf(&p, "%s/%s", root_dir, SYSTEM_CONFIG_UNIT_PATH);
116 p = strdup(SYSTEM_CONFIG_UNIT_PATH);
120 case UNIT_FILE_GLOBAL:
126 p = strdup("/run/systemd/user");
128 p = strdup(USER_CONFIG_UNIT_PATH);
133 if (root_dir || runtime)
136 r = user_config_home(&p);
138 return r < 0 ? r : -ENOENT;
143 assert_not_reached("Bad scope");
153 static int add_file_change(
154 UnitFileChange **changes,
156 UnitFileChangeType type,
158 const char *source) {
164 assert(!changes == !n_changes);
169 c = realloc(*changes, (*n_changes + 1) * sizeof(UnitFileChange));
177 c[i].path = strdup(path);
182 c[i].source = strdup(source);
194 static int mark_symlink_for_removal(
195 Set **remove_symlinks_to,
203 r = set_ensure_allocated(remove_symlinks_to, string_hash_func, string_compare_func);
211 path_kill_slashes(n);
213 r = set_consume(*remove_symlinks_to, n);
215 return r == -EEXIST ? 0 : r;
220 static int remove_marked_symlinks_fd(
221 Set *remove_symlinks_to,
224 const char *config_path,
226 UnitFileChange **changes,
228 char** instance_whitelist) {
230 _cleanup_closedir_ DIR *d = NULL;
233 assert(remove_symlinks_to);
252 if (!de && errno != 0) {
260 if (ignore_file(de->d_name))
263 dirent_ensure_type(d, de);
265 if (de->d_type == DT_DIR) {
267 _cleanup_free_ char *p = NULL;
269 nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
279 p = path_make_absolute(de->d_name, path);
285 /* This will close nfd, regardless whether it succeeds or not */
286 q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, deleted, changes, n_changes, instance_whitelist);
290 } else if (de->d_type == DT_LNK) {
291 _cleanup_free_ char *p = NULL, *dest = NULL;
295 if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
298 if (unit_name_is_instance(de->d_name) &&
299 instance_whitelist &&
300 !strv_contains(instance_whitelist, de->d_name)) {
302 _cleanup_free_ char *w;
304 /* OK, the file is not listed directly
305 * in the whitelist, so let's check if
306 * the template of it might be
309 w = unit_name_template(de->d_name);
313 if (!strv_contains(instance_whitelist, w))
317 p = path_make_absolute(de->d_name, path);
321 q = readlink_and_canonicalize(p, &dest);
332 set_get(remove_symlinks_to, dest) ||
333 set_get(remove_symlinks_to, basename(dest));
338 if (unlink(p) < 0 && errno != ENOENT) {
344 path_kill_slashes(p);
345 rmdir_parents(p, config_path);
346 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, p, NULL);
348 if (!set_get(remove_symlinks_to, p)) {
350 q = mark_symlink_for_removal(&remove_symlinks_to, p);
363 static int remove_marked_symlinks(
364 Set *remove_symlinks_to,
365 const char *config_path,
366 UnitFileChange **changes,
368 char** instance_whitelist) {
370 _cleanup_close_ int fd = -1;
376 if (set_size(remove_symlinks_to) <= 0)
379 fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
387 cfd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
393 /* This takes possession of cfd and closes it */
394 q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, &deleted, changes, n_changes, instance_whitelist);
402 static int find_symlinks_fd(
406 const char *config_path,
407 bool *same_name_link) {
410 _cleanup_closedir_ DIR *d = NULL;
416 assert(same_name_link);
429 if (!de && errno != 0)
435 if (ignore_file(de->d_name))
438 dirent_ensure_type(d, de);
440 if (de->d_type == DT_DIR) {
442 _cleanup_free_ char *p = NULL;
444 nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
454 p = path_make_absolute(de->d_name, path);
460 /* This will close nfd, regardless whether it succeeds or not */
461 q = find_symlinks_fd(name, nfd, p, config_path, same_name_link);
467 } else if (de->d_type == DT_LNK) {
468 _cleanup_free_ char *p = NULL, *dest = NULL;
469 bool found_path, found_dest, b = false;
472 /* Acquire symlink name */
473 p = path_make_absolute(de->d_name, path);
477 /* Acquire symlink destination */
478 q = readlink_and_canonicalize(p, &dest);
488 /* Check if the symlink itself matches what we
490 if (path_is_absolute(name))
491 found_path = path_equal(p, name);
493 found_path = streq(de->d_name, name);
495 /* Check if what the symlink points to
496 * matches what we are looking for */
497 if (path_is_absolute(name))
498 found_dest = path_equal(dest, name);
500 found_dest = streq(basename(dest), name);
502 if (found_path && found_dest) {
503 _cleanup_free_ char *t = NULL;
505 /* Filter out same name links in the main
507 t = path_make_absolute(name, config_path);
511 b = path_equal(t, p);
515 *same_name_link = true;
516 else if (found_path || found_dest)
522 static int find_symlinks(
524 const char *config_path,
525 bool *same_name_link) {
531 assert(same_name_link);
533 fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
540 /* This takes possession of fd and closes it */
541 return find_symlinks_fd(name, fd, config_path, config_path, same_name_link);
544 static int find_symlinks_in_scope(
546 const char *root_dir,
548 UnitFileState *state) {
551 _cleanup_free_ char *path2 = NULL;
552 bool same_name_link_runtime = false, same_name_link = false;
555 assert(scope < _UNIT_FILE_SCOPE_MAX);
558 if (scope == UNIT_FILE_SYSTEM || scope == UNIT_FILE_GLOBAL) {
559 _cleanup_free_ char *path = NULL;
561 /* First look in runtime config path */
562 r = get_config_path(scope, true, root_dir, &path);
566 r = find_symlinks(name, path, &same_name_link_runtime);
570 *state = UNIT_FILE_ENABLED_RUNTIME;
575 /* Then look in the normal config path */
576 r = get_config_path(scope, false, root_dir, &path2);
580 r = find_symlinks(name, path2, &same_name_link);
584 *state = UNIT_FILE_ENABLED;
588 /* Hmm, we didn't find it, but maybe we found the same name
590 if (same_name_link_runtime) {
591 *state = UNIT_FILE_LINKED_RUNTIME;
593 } else if (same_name_link) {
594 *state = UNIT_FILE_LINKED;
604 const char *root_dir,
607 UnitFileChange **changes,
608 unsigned *n_changes) {
611 _cleanup_free_ char *prefix = NULL;
615 assert(scope < _UNIT_FILE_SCOPE_MAX);
617 r = get_config_path(scope, runtime, root_dir, &prefix);
621 STRV_FOREACH(i, files) {
622 _cleanup_free_ char *path = NULL;
624 if (!unit_name_is_valid(*i, TEMPLATE_VALID)) {
630 path = path_make_absolute(*i, prefix);
636 if (symlink("/dev/null", path) >= 0) {
637 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null");
641 if (errno == EEXIST) {
643 if (null_or_empty_path(path) > 0)
647 if (symlink_atomic("/dev/null", path) >= 0) {
648 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
649 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null");
665 int unit_file_unmask(
668 const char *root_dir,
670 UnitFileChange **changes,
671 unsigned *n_changes) {
673 char **i, *config_path = NULL;
675 Set *remove_symlinks_to = NULL;
678 assert(scope < _UNIT_FILE_SCOPE_MAX);
680 r = get_config_path(scope, runtime, root_dir, &config_path);
684 STRV_FOREACH(i, files) {
687 if (!unit_name_is_valid(*i, TEMPLATE_VALID)) {
693 path = path_make_absolute(*i, config_path);
699 q = null_or_empty_path(path);
701 if (unlink(path) >= 0) {
702 mark_symlink_for_removal(&remove_symlinks_to, path);
703 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
712 if (q != -ENOENT && r == 0)
720 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
724 set_free_free(remove_symlinks_to);
733 const char *root_dir,
736 UnitFileChange **changes,
737 unsigned *n_changes) {
739 _cleanup_lookup_paths_free_ LookupPaths paths = {};
741 _cleanup_free_ char *config_path = NULL;
745 assert(scope < _UNIT_FILE_SCOPE_MAX);
747 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
751 r = get_config_path(scope, runtime, root_dir, &config_path);
755 STRV_FOREACH(i, files) {
756 _cleanup_free_ char *path = NULL;
762 if (!path_is_absolute(*i) ||
763 !unit_name_is_valid(fn, TEMPLATE_VALID)) {
769 if (lstat(*i, &st) < 0) {
775 if (!S_ISREG(st.st_mode)) {
780 q = in_search_path(*i, paths.unit_path, root_dir);
787 path = path_make_absolute(fn, config_path);
791 if (symlink(*i, path) >= 0) {
792 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, *i);
796 if (errno == EEXIST) {
797 _cleanup_free_ char *dest = NULL;
799 q = readlink_and_make_absolute(path, &dest);
800 if (q < 0 && errno != ENOENT) {
806 if (q >= 0 && path_equal(dest, *i))
810 if (symlink_atomic(*i, path) >= 0) {
811 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
812 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, *i);
828 void unit_file_list_free(Hashmap *h) {
831 while ((i = hashmap_steal_first(h))) {
839 void unit_file_changes_free(UnitFileChange *changes, unsigned n_changes) {
842 assert(changes || n_changes == 0);
847 for (i = 0; i < n_changes; i++) {
848 free(changes[i].path);
849 free(changes[i].source);
855 static void install_info_free(InstallInfo *i) {
860 strv_free(i->aliases);
861 strv_free(i->wanted_by);
862 strv_free(i->required_by);
863 free(i->default_instance);
867 static void install_info_hashmap_free(Hashmap *m) {
873 while ((i = hashmap_steal_first(m)))
874 install_info_free(i);
879 static void install_context_done(InstallContext *c) {
882 install_info_hashmap_free(c->will_install);
883 install_info_hashmap_free(c->have_installed);
885 c->will_install = c->have_installed = NULL;
888 static int install_info_add(
892 InstallInfo *i = NULL;
896 assert(name || path);
899 name = basename(path);
901 if (!unit_name_is_valid(name, TEMPLATE_VALID))
904 if (hashmap_get(c->have_installed, name) ||
905 hashmap_get(c->will_install, name))
908 r = hashmap_ensure_allocated(&c->will_install, string_hash_func, string_compare_func);
912 i = new0(InstallInfo, 1);
916 i->name = strdup(name);
923 i->path = strdup(path);
930 r = hashmap_put(c->will_install, i->name, i);
938 install_info_free(i);
943 static int install_info_add_auto(
945 const char *name_or_path) {
948 assert(name_or_path);
950 if (path_is_absolute(name_or_path))
951 return install_info_add(c, NULL, name_or_path);
953 return install_info_add(c, name_or_path, NULL);
956 static int config_parse_also(
958 const char *filename,
961 unsigned section_line,
971 InstallContext *c = data;
977 FOREACH_WORD_QUOTED(w, l, rvalue, state) {
978 _cleanup_free_ char *n;
985 r = install_info_add(c, n, NULL);
993 static int config_parse_user(
995 const char *filename,
998 unsigned section_line,
1005 InstallInfo *i = data;
1013 r = install_full_printf(i, rvalue, &printed);
1023 static int config_parse_default_instance(
1025 const char *filename,
1027 const char *section,
1028 unsigned section_line,
1035 InstallInfo *i = data;
1043 r = install_full_printf(i, rvalue, &printed);
1047 if (!unit_instance_is_valid(printed))
1050 free(i->default_instance);
1051 i->default_instance = printed;
1056 static int unit_file_load(
1060 bool allow_symlink) {
1062 const ConfigTableItem items[] = {
1063 { "Install", "Alias", config_parse_strv, 0, &info->aliases },
1064 { "Install", "WantedBy", config_parse_strv, 0, &info->wanted_by },
1065 { "Install", "RequiredBy", config_parse_strv, 0, &info->required_by },
1066 { "Install", "DefaultInstance", config_parse_default_instance, 0, info },
1067 { "Install", "Also", config_parse_also, 0, c },
1068 { "Exec", "User", config_parse_user, 0, info },
1073 _cleanup_fclose_ FILE *f = NULL;
1080 fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|(allow_symlink ? 0 : O_NOFOLLOW));
1084 f = fdopen(fd, "re");
1090 r = config_parse(NULL, path, f, NULL, config_item_table_lookup, (void*) items, true, true, info);
1095 (int) strv_length(info->aliases) +
1096 (int) strv_length(info->wanted_by) +
1097 (int) strv_length(info->required_by);
1100 static int unit_file_search(
1104 const char *root_dir,
1105 bool allow_symlink) {
1117 if (isempty(root_dir))
1120 path = strappenda(root_dir, info->path);
1122 return unit_file_load(c, info, path, allow_symlink);
1127 STRV_FOREACH(p, paths->unit_path) {
1128 _cleanup_free_ char *path = NULL;
1130 if (isempty(root_dir))
1131 path = strjoin(*p, "/", info->name, NULL);
1133 path = strjoin(root_dir, "/", *p, "/", info->name, NULL);
1137 r = unit_file_load(c, info, path, allow_symlink);
1143 if (r != -ENOENT && r != -ELOOP)
1147 if (unit_name_is_instance(info->name)) {
1149 /* Unit file doesn't exist, however instance
1150 * enablement was requested. We will check if it is
1151 * possible to load template unit file. */
1153 _cleanup_free_ char *template = NULL, *template_dir = NULL;
1155 template = unit_name_template(info->name);
1159 STRV_FOREACH(p, paths->unit_path) {
1160 _cleanup_free_ char *path = NULL;
1162 if (isempty(root_dir))
1163 path = strjoin(*p, "/", template, NULL);
1165 path = strjoin(root_dir, "/", *p, "/", template, NULL);
1169 r = unit_file_load(c, info, path, allow_symlink);
1175 if (r != -ENOENT && r != -ELOOP)
1183 static int unit_file_can_install(
1185 const char *root_dir,
1187 bool allow_symlink) {
1189 _cleanup_install_context_done_ InstallContext c = {};
1196 r = install_info_add_auto(&c, name);
1200 assert_se(i = hashmap_first(c.will_install));
1202 r = unit_file_search(&c, i, paths, root_dir, allow_symlink);
1206 (int) strv_length(i->aliases) +
1207 (int) strv_length(i->wanted_by) +
1208 (int) strv_length(i->required_by);
1213 static int create_symlink(
1214 const char *old_path,
1215 const char *new_path,
1217 UnitFileChange **changes,
1218 unsigned *n_changes) {
1220 _cleanup_free_ char *dest = NULL;
1226 mkdir_parents_label(new_path, 0755);
1228 if (symlink(old_path, new_path) >= 0) {
1229 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
1233 if (errno != EEXIST)
1236 r = readlink_and_make_absolute(new_path, &dest);
1240 if (path_equal(dest, old_path))
1246 r = symlink_atomic(old_path, new_path);
1250 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL);
1251 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
1256 static int install_info_symlink_alias(
1258 const char *config_path,
1260 UnitFileChange **changes,
1261 unsigned *n_changes) {
1267 assert(config_path);
1269 STRV_FOREACH(s, i->aliases) {
1270 _cleanup_free_ char *alias_path = NULL, *dst = NULL;
1272 q = install_full_printf(i, *s, &dst);
1276 alias_path = path_make_absolute(dst, config_path);
1280 q = create_symlink(i->path, alias_path, force, changes, n_changes);
1288 static int install_info_symlink_wants(
1290 const char *config_path,
1294 UnitFileChange **changes,
1295 unsigned *n_changes) {
1297 _cleanup_free_ char *buf = NULL;
1303 assert(config_path);
1305 if (unit_name_is_template(i->name) && i->default_instance) {
1306 buf = unit_name_replace_instance(i->name, i->default_instance);
1314 STRV_FOREACH(s, list) {
1315 _cleanup_free_ char *path = NULL, *dst = NULL;
1317 q = install_full_printf(i, *s, &dst);
1321 if (!unit_name_is_valid(dst, TEMPLATE_VALID)) {
1326 path = strjoin(config_path, "/", dst, suffix, n, NULL);
1330 q = create_symlink(i->path, path, force, changes, n_changes);
1338 static int install_info_symlink_link(
1341 const char *config_path,
1342 const char *root_dir,
1344 UnitFileChange **changes,
1345 unsigned *n_changes) {
1347 _cleanup_free_ char *path = NULL;
1352 assert(config_path);
1355 r = in_search_path(i->path, paths->unit_path, root_dir);
1359 path = strjoin(config_path, "/", i->name, NULL);
1363 return create_symlink(i->path, path, force, changes, n_changes);
1366 static int install_info_apply(
1369 const char *config_path,
1370 const char *root_dir,
1372 UnitFileChange **changes,
1373 unsigned *n_changes) {
1379 assert(config_path);
1381 r = install_info_symlink_alias(i, config_path, force, changes, n_changes);
1383 q = install_info_symlink_wants(i, config_path, i->wanted_by, ".wants/", force, changes, n_changes);
1387 q = install_info_symlink_wants(i, config_path, i->required_by, ".requires/", force, changes, n_changes);
1391 q = install_info_symlink_link(i, paths, config_path, root_dir, force, changes, n_changes);
1398 static int install_context_apply(
1401 const char *config_path,
1402 const char *root_dir,
1404 UnitFileChange **changes,
1405 unsigned *n_changes) {
1412 assert(config_path);
1414 while ((i = hashmap_first(c->will_install))) {
1416 q = hashmap_ensure_allocated(&c->have_installed, string_hash_func, string_compare_func);
1420 assert_se(hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
1422 q = unit_file_search(c, i, paths, root_dir, false);
1431 q = install_info_apply(i, paths, config_path, root_dir, force, changes, n_changes);
1432 if (r >= 0 && q < 0)
1439 static int install_context_mark_for_removal(
1442 Set **remove_symlinks_to,
1443 const char *config_path,
1444 const char *root_dir) {
1451 assert(config_path);
1453 /* Marks all items for removal */
1455 while ((i = hashmap_first(c->will_install))) {
1457 q = hashmap_ensure_allocated(&c->have_installed, string_hash_func, string_compare_func);
1461 assert_se(hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
1463 q = unit_file_search(c, i, paths, root_dir, false);
1474 if (unit_name_is_instance(i->name)) {
1478 unit_file = basename(i->path);
1480 if (unit_name_is_instance(unit_file))
1481 /* unit file named as instance exists, thus all symlinks
1482 * pointing to it will be removed */
1483 q = mark_symlink_for_removal(remove_symlinks_to, i->name);
1485 /* does not exist, thus we will mark for removal symlinks
1486 * to template unit file */
1487 q = mark_symlink_for_removal(remove_symlinks_to, unit_file);
1489 /* If i->path is not set, it means that we didn't actually find
1490 * the unit file. But we can still remove symlinks to the
1491 * nonexistent template. */
1492 unit_file = unit_name_template(i->name);
1496 q = mark_symlink_for_removal(remove_symlinks_to, unit_file);
1500 q = mark_symlink_for_removal(remove_symlinks_to, i->name);
1502 if (r >= 0 && q < 0)
1509 int unit_file_enable(
1510 UnitFileScope scope,
1512 const char *root_dir,
1515 UnitFileChange **changes,
1516 unsigned *n_changes) {
1518 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1519 _cleanup_install_context_done_ InstallContext c = {};
1521 _cleanup_free_ char *config_path = NULL;
1525 assert(scope < _UNIT_FILE_SCOPE_MAX);
1527 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1531 r = get_config_path(scope, runtime, root_dir, &config_path);
1535 STRV_FOREACH(i, files) {
1536 r = install_info_add_auto(&c, *i);
1541 /* This will return the number of symlink rules that were
1542 supposed to be created, not the ones actually created. This is
1543 useful to determine whether the passed files had any
1544 installation data at all. */
1546 return install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes);
1549 int unit_file_disable(
1550 UnitFileScope scope,
1552 const char *root_dir,
1554 UnitFileChange **changes,
1555 unsigned *n_changes) {
1557 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1558 _cleanup_install_context_done_ InstallContext c = {};
1560 _cleanup_free_ char *config_path = NULL;
1561 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
1565 assert(scope < _UNIT_FILE_SCOPE_MAX);
1567 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1571 r = get_config_path(scope, runtime, root_dir, &config_path);
1575 STRV_FOREACH(i, files) {
1576 r = install_info_add_auto(&c, *i);
1581 r = install_context_mark_for_removal(&c, &paths, &remove_symlinks_to, config_path, root_dir);
1583 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
1590 int unit_file_reenable(
1591 UnitFileScope scope,
1593 const char *root_dir,
1596 UnitFileChange **changes,
1597 unsigned *n_changes) {
1600 r = unit_file_disable(scope, runtime, root_dir, files,
1601 changes, n_changes);
1605 return unit_file_enable(scope, runtime, root_dir, files, force,
1606 changes, n_changes);
1609 int unit_file_set_default(
1610 UnitFileScope scope,
1611 const char *root_dir,
1614 UnitFileChange **changes,
1615 unsigned *n_changes) {
1617 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1618 _cleanup_install_context_done_ InstallContext c = {};
1619 _cleanup_free_ char *config_path = NULL;
1622 InstallInfo *i = NULL;
1625 assert(scope < _UNIT_FILE_SCOPE_MAX);
1628 if (unit_name_to_type(file) != UNIT_TARGET)
1631 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1635 r = get_config_path(scope, false, root_dir, &config_path);
1639 r = install_info_add_auto(&c, file);
1643 assert_se(i = hashmap_first(c.will_install));
1645 r = unit_file_search(&c, i, &paths, root_dir, false);
1649 path = strappenda(config_path, "/" SPECIAL_DEFAULT_TARGET);
1651 r = create_symlink(i->path, path, force, changes, n_changes);
1658 int unit_file_get_default(
1659 UnitFileScope scope,
1660 const char *root_dir,
1663 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1668 assert(scope < _UNIT_FILE_SCOPE_MAX);
1671 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1675 STRV_FOREACH(p, paths.unit_path) {
1676 _cleanup_free_ char *path = NULL, *tmp = NULL;
1679 if (isempty(root_dir))
1680 path = strappend(*p, "/" SPECIAL_DEFAULT_TARGET);
1682 path = strjoin(root_dir, "/", *p, "/" SPECIAL_DEFAULT_TARGET, NULL);
1687 r = readlink_malloc(path, &tmp);
1690 else if (r == -EINVAL)
1692 n = strdup(SPECIAL_DEFAULT_TARGET);
1696 n = strdup(basename(tmp));
1708 UnitFileState unit_file_get_state(
1709 UnitFileScope scope,
1710 const char *root_dir,
1713 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1714 UnitFileState state = _UNIT_FILE_STATE_INVALID;
1716 _cleanup_free_ char *path = NULL;
1720 assert(scope < _UNIT_FILE_SCOPE_MAX);
1723 if (root_dir && scope != UNIT_FILE_SYSTEM)
1726 if (!unit_name_is_valid(name, TEMPLATE_VALID))
1729 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1733 STRV_FOREACH(i, paths.unit_path) {
1741 asprintf(&path, "%s/%s/%s", root_dir, *i, name);
1743 asprintf(&path, "%s/%s", *i, name);
1748 partial = path + strlen(root_dir) + 1;
1753 * Search for a unit file in our default paths, to
1754 * be sure, that there are no broken symlinks.
1756 if (lstat(path, &st) < 0) {
1758 if (errno != ENOENT)
1761 if (!unit_name_is_instance(name))
1764 if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode))
1767 r = null_or_empty_path(path);
1768 if (r < 0 && r != -ENOENT)
1771 state = path_startswith(*i, "/run") ?
1772 UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
1777 r = find_symlinks_in_scope(scope, root_dir, name, &state);
1783 r = unit_file_can_install(&paths, root_dir, partial, true);
1784 if (r < 0 && errno != ENOENT)
1787 return UNIT_FILE_DISABLED;
1789 return UNIT_FILE_STATIC;
1792 return r < 0 ? r : state;
1795 int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name) {
1796 _cleanup_strv_free_ char **files = NULL;
1801 assert(scope < _UNIT_FILE_SCOPE_MAX);
1804 if (scope == UNIT_FILE_SYSTEM)
1805 r = conf_files_list(&files, ".preset", root_dir,
1806 "/etc/systemd/system-preset",
1807 "/usr/local/lib/systemd/system-preset",
1808 "/usr/lib/systemd/system-preset",
1809 #ifdef HAVE_SPLIT_USR
1810 "/lib/systemd/system-preset",
1813 else if (scope == UNIT_FILE_GLOBAL)
1814 r = conf_files_list(&files, ".preset", root_dir,
1815 "/etc/systemd/user-preset",
1816 "/usr/local/lib/systemd/user-preset",
1817 "/usr/lib/systemd/user-preset",
1825 STRV_FOREACH(i, files) {
1826 _cleanup_free_ char *buf = NULL;
1827 _cleanup_fclose_ FILE *f;
1831 p = buf = strjoin(root_dir, "/", *i, NULL);
1837 if (errno == ENOENT)
1844 char line[LINE_MAX], *l;
1846 if (!fgets(line, sizeof(line), f))
1853 if (strchr(COMMENTS "\n", *l))
1856 if (first_word(l, "enable")) {
1858 l += strspn(l, WHITESPACE);
1860 if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
1861 log_debug("Preset file says enable %s.", name);
1865 } else if (first_word(l, "disable")) {
1867 l += strspn(l, WHITESPACE);
1869 if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
1870 log_debug("Preset file says disable %s.", name);
1875 log_debug("Couldn't parse line '%s'", l);
1879 /* Default is "enable" */
1880 log_debug("Preset file doesn't say anything about %s, enabling.", name);
1884 int unit_file_preset(
1885 UnitFileScope scope,
1887 const char *root_dir,
1889 UnitFilePresetMode mode,
1891 UnitFileChange **changes,
1892 unsigned *n_changes) {
1894 _cleanup_install_context_done_ InstallContext plus = {}, minus = {};
1895 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1896 _cleanup_free_ char *config_path = NULL;
1901 assert(scope < _UNIT_FILE_SCOPE_MAX);
1902 assert(mode < _UNIT_FILE_PRESET_MODE_MAX);
1904 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1908 r = get_config_path(scope, runtime, root_dir, &config_path);
1912 STRV_FOREACH(i, files) {
1914 if (!unit_name_is_valid(*i, TEMPLATE_VALID))
1917 r = unit_file_query_preset(scope, root_dir, *i);
1921 if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
1922 r = install_info_add_auto(&plus, *i);
1923 else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
1924 r = install_info_add_auto(&minus, *i);
1933 if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
1934 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
1936 r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
1938 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
1943 if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
1944 /* Returns number of symlinks that where supposed to be installed. */
1945 q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
1953 int unit_file_preset_all(
1954 UnitFileScope scope,
1956 const char *root_dir,
1957 UnitFilePresetMode mode,
1959 UnitFileChange **changes,
1960 unsigned *n_changes) {
1962 _cleanup_install_context_done_ InstallContext plus = {}, minus = {};
1963 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1964 _cleanup_free_ char *config_path = NULL;
1969 assert(scope < _UNIT_FILE_SCOPE_MAX);
1970 assert(mode < _UNIT_FILE_PRESET_MODE_MAX);
1972 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1976 r = get_config_path(scope, runtime, root_dir, &config_path);
1980 STRV_FOREACH(i, paths.unit_path) {
1981 _cleanup_closedir_ DIR *d = NULL;
1982 _cleanup_free_ char *buf = NULL;
1983 const char *units_dir;
1985 if (!isempty(root_dir)) {
1986 buf = strjoin(root_dir, "/", *i, NULL);
1994 d = opendir(units_dir);
1996 if (errno == ENOENT)
2007 if (!de && errno != 0)
2013 if (ignore_file(de->d_name))
2016 if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
2019 dirent_ensure_type(d, de);
2021 if (de->d_type != DT_REG)
2024 r = unit_file_query_preset(scope, root_dir, de->d_name);
2028 if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
2029 r = install_info_add_auto(&plus, de->d_name);
2030 else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
2031 r = install_info_add_auto(&minus, de->d_name);
2041 if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
2042 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
2044 r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
2046 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, NULL);
2051 if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
2052 q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
2060 static void unitfilelist_free(UnitFileList **f) {
2067 #define _cleanup_unitfilelist_free_ _cleanup_(unitfilelist_free)
2069 int unit_file_get_list(
2070 UnitFileScope scope,
2071 const char *root_dir,
2074 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2079 assert(scope < _UNIT_FILE_SCOPE_MAX);
2082 if (root_dir && scope != UNIT_FILE_SYSTEM)
2085 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
2089 STRV_FOREACH(i, paths.unit_path) {
2090 _cleanup_closedir_ DIR *d = NULL;
2091 _cleanup_free_ char *buf = NULL;
2092 const char *units_dir;
2094 if (!isempty(root_dir)) {
2095 buf = strjoin(root_dir, "/", *i, NULL);
2103 d = opendir(units_dir);
2105 if (errno == ENOENT)
2112 _cleanup_unitfilelist_free_ UnitFileList *f = NULL;
2117 if (!de && errno != 0)
2123 if (ignore_file(de->d_name))
2126 if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
2129 if (hashmap_get(h, de->d_name))
2132 dirent_ensure_type(d, de);
2134 if (!IN_SET(de->d_type, DT_LNK, DT_REG))
2137 f = new0(UnitFileList, 1);
2141 f->path = path_make_absolute(de->d_name, units_dir);
2145 r = null_or_empty_path(f->path);
2146 if (r < 0 && r != -ENOENT)
2150 path_startswith(*i, "/run") ?
2151 UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
2155 r = find_symlinks_in_scope(scope, root_dir, de->d_name, &f->state);
2159 f->state = UNIT_FILE_ENABLED;
2163 r = unit_file_can_install(&paths, root_dir, f->path, true);
2164 if (r == -EINVAL || /* Invalid setting? */
2165 r == -EBADMSG || /* Invalid format? */
2166 r == -ENOENT /* Included file not found? */)
2167 f->state = UNIT_FILE_INVALID;
2171 f->state = UNIT_FILE_DISABLED;
2173 f->state = UNIT_FILE_STATIC;
2176 r = hashmap_put(h, basename(f->path), f);
2179 f = NULL; /* prevent cleanup */
2186 static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
2187 [UNIT_FILE_ENABLED] = "enabled",
2188 [UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtime",
2189 [UNIT_FILE_LINKED] = "linked",
2190 [UNIT_FILE_LINKED_RUNTIME] = "linked-runtime",
2191 [UNIT_FILE_MASKED] = "masked",
2192 [UNIT_FILE_MASKED_RUNTIME] = "masked-runtime",
2193 [UNIT_FILE_STATIC] = "static",
2194 [UNIT_FILE_DISABLED] = "disabled",
2195 [UNIT_FILE_INVALID] = "invalid",
2198 DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);
2200 static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = {
2201 [UNIT_FILE_SYMLINK] = "symlink",
2202 [UNIT_FILE_UNLINK] = "unlink",
2205 DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
2207 static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MODE_MAX] = {
2208 [UNIT_FILE_PRESET_FULL] = "full",
2209 [UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
2210 [UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
2213 DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode, UnitFilePresetMode);