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/>.
28 #include "conf-files.h"
29 #include "conf-parser.h"
30 #include "dirent-util.h"
33 #include "install-printf.h"
36 #include "path-lookup.h"
37 #include "path-util.h"
40 #include "string-util.h"
42 #include "unit-name.h"
46 OrderedHashmap
*will_install
;
47 OrderedHashmap
*have_installed
;
50 static int in_search_path(const char *path
, char **search
) {
51 _cleanup_free_
char *parent
= NULL
;
55 parent
= dirname_malloc(path
);
59 return strv_contains(search
, parent
);
62 static int get_config_path(UnitFileScope scope
, bool runtime
, const char *root_dir
, char **ret
) {
67 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
72 case UNIT_FILE_SYSTEM
:
75 p
= path_join(root_dir
, "/run/systemd/system", NULL
);
77 p
= path_join(root_dir
, SYSTEM_CONFIG_UNIT_PATH
, NULL
);
80 case UNIT_FILE_GLOBAL
:
86 p
= strdup("/run/systemd/user");
88 p
= strdup(USER_CONFIG_UNIT_PATH
);
97 r
= user_runtime_dir(&p
);
99 r
= user_config_home(&p
);
102 return r
< 0 ? r
: -ENOENT
;
107 assert_not_reached("Bad scope");
117 static int mark_symlink_for_removal(
118 Set
**remove_symlinks_to
,
126 r
= set_ensure_allocated(remove_symlinks_to
, &string_hash_ops
);
134 path_kill_slashes(n
);
136 r
= set_consume(*remove_symlinks_to
, n
);
138 return r
== -EEXIST
? 0 : r
;
143 static int remove_marked_symlinks_fd(
144 Set
*remove_symlinks_to
,
147 const char *config_path
,
149 UnitFileChange
**changes
,
151 char** instance_whitelist
) {
153 _cleanup_closedir_
DIR *d
= NULL
;
156 assert(remove_symlinks_to
);
175 if (!de
&& errno
!= 0) {
183 if (hidden_file(de
->d_name
))
186 dirent_ensure_type(d
, de
);
188 if (de
->d_type
== DT_DIR
) {
190 _cleanup_free_
char *p
= NULL
;
192 nfd
= openat(fd
, de
->d_name
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
|O_NOFOLLOW
);
202 p
= path_make_absolute(de
->d_name
, path
);
208 /* This will close nfd, regardless whether it succeeds or not */
209 q
= remove_marked_symlinks_fd(remove_symlinks_to
, nfd
, p
, config_path
, deleted
, changes
, n_changes
, instance_whitelist
);
213 } else if (de
->d_type
== DT_LNK
) {
214 _cleanup_free_
char *p
= NULL
, *dest
= NULL
;
218 if (!unit_name_is_valid(de
->d_name
, UNIT_NAME_ANY
))
221 if (unit_name_is_valid(de
->d_name
, UNIT_NAME_INSTANCE
) &&
222 instance_whitelist
&&
223 !strv_contains(instance_whitelist
, de
->d_name
)) {
225 _cleanup_free_
char *w
= NULL
;
227 /* OK, the file is not listed directly
228 * in the whitelist, so let's check if
229 * the template of it might be
232 r
= unit_name_template(de
->d_name
, &w
);
236 if (!strv_contains(instance_whitelist
, w
))
240 p
= path_make_absolute(de
->d_name
, path
);
244 q
= readlink_and_canonicalize(p
, &dest
);
255 set_get(remove_symlinks_to
, dest
) ||
256 set_get(remove_symlinks_to
, basename(dest
));
261 if (unlink(p
) < 0 && errno
!= ENOENT
) {
267 path_kill_slashes(p
);
268 rmdir_parents(p
, config_path
);
269 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_UNLINK
, p
, NULL
);
271 if (!set_get(remove_symlinks_to
, p
)) {
273 q
= mark_symlink_for_removal(&remove_symlinks_to
, p
);
286 static int remove_marked_symlinks(
287 Set
*remove_symlinks_to
,
288 const char *config_path
,
289 UnitFileChange
**changes
,
291 char** instance_whitelist
) {
293 _cleanup_close_
int fd
= -1;
299 if (set_size(remove_symlinks_to
) <= 0)
302 fd
= open(config_path
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
|O_NOFOLLOW
);
310 cfd
= fcntl(fd
, F_DUPFD_CLOEXEC
, 3);
316 /* This takes possession of cfd and closes it */
317 q
= remove_marked_symlinks_fd(remove_symlinks_to
, cfd
, config_path
, config_path
, &deleted
, changes
, n_changes
, instance_whitelist
);
325 static int find_symlinks_fd(
329 const char *config_path
,
330 bool *same_name_link
) {
333 _cleanup_closedir_
DIR *d
= NULL
;
339 assert(same_name_link
);
352 if (!de
&& errno
!= 0)
358 if (hidden_file(de
->d_name
))
361 dirent_ensure_type(d
, de
);
363 if (de
->d_type
== DT_DIR
) {
365 _cleanup_free_
char *p
= NULL
;
367 nfd
= openat(fd
, de
->d_name
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
|O_NOFOLLOW
);
377 p
= path_make_absolute(de
->d_name
, path
);
383 /* This will close nfd, regardless whether it succeeds or not */
384 q
= find_symlinks_fd(name
, nfd
, p
, config_path
, same_name_link
);
390 } else if (de
->d_type
== DT_LNK
) {
391 _cleanup_free_
char *p
= NULL
, *dest
= NULL
;
392 bool found_path
, found_dest
, b
= false;
395 /* Acquire symlink name */
396 p
= path_make_absolute(de
->d_name
, path
);
400 /* Acquire symlink destination */
401 q
= readlink_and_canonicalize(p
, &dest
);
411 /* Check if the symlink itself matches what we
413 if (path_is_absolute(name
))
414 found_path
= path_equal(p
, name
);
416 found_path
= streq(de
->d_name
, name
);
418 /* Check if what the symlink points to
419 * matches what we are looking for */
420 if (path_is_absolute(name
))
421 found_dest
= path_equal(dest
, name
);
423 found_dest
= streq(basename(dest
), name
);
425 if (found_path
&& found_dest
) {
426 _cleanup_free_
char *t
= NULL
;
428 /* Filter out same name links in the main
430 t
= path_make_absolute(name
, config_path
);
434 b
= path_equal(t
, p
);
438 *same_name_link
= true;
439 else if (found_path
|| found_dest
)
445 static int find_symlinks(
447 const char *config_path
,
448 bool *same_name_link
) {
454 assert(same_name_link
);
456 fd
= open(config_path
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
|O_NOFOLLOW
);
463 /* This takes possession of fd and closes it */
464 return find_symlinks_fd(name
, fd
, config_path
, config_path
, same_name_link
);
467 static int find_symlinks_in_scope(
469 const char *root_dir
,
471 UnitFileState
*state
) {
474 _cleanup_free_
char *normal_path
= NULL
, *runtime_path
= NULL
;
475 bool same_name_link_runtime
= false, same_name_link
= false;
478 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
481 /* First look in runtime config path */
482 r
= get_config_path(scope
, true, root_dir
, &normal_path
);
486 r
= find_symlinks(name
, normal_path
, &same_name_link_runtime
);
490 *state
= UNIT_FILE_ENABLED_RUNTIME
;
494 /* Then look in the normal config path */
495 r
= get_config_path(scope
, false, root_dir
, &runtime_path
);
499 r
= find_symlinks(name
, runtime_path
, &same_name_link
);
503 *state
= UNIT_FILE_ENABLED
;
507 /* Hmm, we didn't find it, but maybe we found the same name
509 if (same_name_link_runtime
) {
510 *state
= UNIT_FILE_LINKED_RUNTIME
;
512 } else if (same_name_link
) {
513 *state
= UNIT_FILE_LINKED
;
523 const char *root_dir
,
526 UnitFileChange
**changes
,
527 unsigned *n_changes
) {
530 _cleanup_free_
char *prefix
= NULL
;
534 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
536 r
= get_config_path(scope
, runtime
, root_dir
, &prefix
);
540 STRV_FOREACH(i
, files
) {
541 _cleanup_free_
char *path
= NULL
;
543 if (!unit_name_is_valid(*i
, UNIT_NAME_ANY
)) {
549 path
= path_make_absolute(*i
, prefix
);
555 if (symlink("/dev/null", path
) >= 0) {
556 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_SYMLINK
, path
, "/dev/null");
560 if (errno
== EEXIST
) {
562 if (null_or_empty_path(path
) > 0)
566 if (symlink_atomic("/dev/null", path
) >= 0) {
567 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_UNLINK
, path
, NULL
);
568 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_SYMLINK
, path
, "/dev/null");
584 int unit_file_unmask(
587 const char *root_dir
,
589 UnitFileChange
**changes
,
590 unsigned *n_changes
) {
592 char **i
, *config_path
= NULL
;
594 Set
*remove_symlinks_to
= NULL
;
597 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
599 r
= get_config_path(scope
, runtime
, root_dir
, &config_path
);
603 STRV_FOREACH(i
, files
) {
604 _cleanup_free_
char *path
= NULL
;
606 if (!unit_name_is_valid(*i
, UNIT_NAME_ANY
)) {
612 path
= path_make_absolute(*i
, config_path
);
618 q
= null_or_empty_path(path
);
620 if (unlink(path
) < 0)
623 q
= mark_symlink_for_removal(&remove_symlinks_to
, path
);
624 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_UNLINK
, path
, NULL
);
628 if (q
!= -ENOENT
&& r
== 0)
634 q
= remove_marked_symlinks(remove_symlinks_to
, config_path
, changes
, n_changes
, files
);
638 set_free_free(remove_symlinks_to
);
647 const char *root_dir
,
650 UnitFileChange
**changes
,
651 unsigned *n_changes
) {
653 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
655 _cleanup_free_
char *config_path
= NULL
;
659 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
661 r
= lookup_paths_init_from_scope(&paths
, scope
, root_dir
);
665 r
= get_config_path(scope
, runtime
, root_dir
, &config_path
);
669 STRV_FOREACH(i
, files
) {
670 _cleanup_free_
char *path
= NULL
;
676 if (!path_is_absolute(*i
) ||
677 !unit_name_is_valid(fn
, UNIT_NAME_ANY
)) {
683 if (lstat(*i
, &st
) < 0) {
689 if (!S_ISREG(st
.st_mode
)) {
694 q
= in_search_path(*i
, paths
.unit_path
);
701 path
= path_make_absolute(fn
, config_path
);
705 if (symlink(*i
, path
) >= 0) {
706 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_SYMLINK
, path
, *i
);
710 if (errno
== EEXIST
) {
711 _cleanup_free_
char *dest
= NULL
;
713 q
= readlink_and_make_absolute(path
, &dest
);
714 if (q
< 0 && errno
!= ENOENT
) {
720 if (q
>= 0 && path_equal(dest
, *i
))
724 if (symlink_atomic(*i
, path
) >= 0) {
725 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_UNLINK
, path
, NULL
);
726 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_SYMLINK
, path
, *i
);
742 void unit_file_list_free(Hashmap
*h
) {
745 while ((i
= hashmap_steal_first(h
))) {
753 int unit_file_changes_add(
754 UnitFileChange
**changes
,
756 UnitFileChangeType type
,
758 const char *source
) {
764 assert(!changes
== !n_changes
);
769 c
= realloc(*changes
, (*n_changes
+ 1) * sizeof(UnitFileChange
));
777 c
[i
].path
= strdup(path
);
781 path_kill_slashes(c
[i
].path
);
784 c
[i
].source
= strdup(source
);
790 path_kill_slashes(c
[i
].path
);
798 void unit_file_changes_free(UnitFileChange
*changes
, unsigned n_changes
) {
801 assert(changes
|| n_changes
== 0);
806 for (i
= 0; i
< n_changes
; i
++) {
807 free(changes
[i
].path
);
808 free(changes
[i
].source
);
814 static void install_info_free(UnitFileInstallInfo
*i
) {
819 strv_free(i
->aliases
);
820 strv_free(i
->wanted_by
);
821 strv_free(i
->required_by
);
823 free(i
->default_instance
);
827 static void install_info_hashmap_free(OrderedHashmap
*m
) {
828 UnitFileInstallInfo
*i
;
833 while ((i
= ordered_hashmap_steal_first(m
)))
834 install_info_free(i
);
836 ordered_hashmap_free(m
);
839 static void install_context_done(InstallContext
*c
) {
842 install_info_hashmap_free(c
->will_install
);
843 install_info_hashmap_free(c
->have_installed
);
845 c
->will_install
= c
->have_installed
= NULL
;
848 static int install_info_add(
852 UnitFileInstallInfo
*i
= NULL
;
856 assert(name
|| path
);
859 name
= basename(path
);
861 if (!unit_name_is_valid(name
, UNIT_NAME_ANY
))
864 if (ordered_hashmap_get(c
->have_installed
, name
) ||
865 ordered_hashmap_get(c
->will_install
, name
))
868 r
= ordered_hashmap_ensure_allocated(&c
->will_install
, &string_hash_ops
);
872 i
= new0(UnitFileInstallInfo
, 1);
876 i
->name
= strdup(name
);
883 i
->path
= strdup(path
);
890 r
= ordered_hashmap_put(c
->will_install
, i
->name
, i
);
898 install_info_free(i
);
903 static int install_info_add_auto(
905 const char *name_or_path
) {
908 assert(name_or_path
);
910 if (path_is_absolute(name_or_path
))
911 return install_info_add(c
, NULL
, name_or_path
);
913 return install_info_add(c
, name_or_path
, NULL
);
916 static int config_parse_also(
918 const char *filename
,
921 unsigned section_line
,
929 const char *word
, *state
;
930 InstallContext
*c
= data
;
931 UnitFileInstallInfo
*i
= userdata
;
937 FOREACH_WORD_QUOTED(word
, l
, rvalue
, state
) {
938 _cleanup_free_
char *n
;
941 n
= strndup(word
, l
);
945 r
= install_info_add(c
, n
, NULL
);
949 r
= strv_extend(&i
->also
, n
);
954 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Trailing garbage, ignoring.");
959 static int config_parse_user(
961 const char *filename
,
964 unsigned section_line
,
971 UnitFileInstallInfo
*i
= data
;
979 r
= install_full_printf(i
, rvalue
, &printed
);
989 static int config_parse_default_instance(
991 const char *filename
,
994 unsigned section_line
,
1001 UnitFileInstallInfo
*i
= data
;
1009 r
= install_full_printf(i
, rvalue
, &printed
);
1013 if (!unit_instance_is_valid(printed
)) {
1018 free(i
->default_instance
);
1019 i
->default_instance
= printed
;
1024 static int unit_file_load(
1026 UnitFileInstallInfo
*info
,
1028 const char *root_dir
,
1033 const ConfigTableItem items
[] = {
1034 { "Install", "Alias", config_parse_strv
, 0, &info
->aliases
},
1035 { "Install", "WantedBy", config_parse_strv
, 0, &info
->wanted_by
},
1036 { "Install", "RequiredBy", config_parse_strv
, 0, &info
->required_by
},
1037 { "Install", "DefaultInstance", config_parse_default_instance
, 0, info
},
1038 { "Install", "Also", config_parse_also
, 0, c
},
1039 { "Exec", "User", config_parse_user
, 0, info
},
1043 _cleanup_fclose_
FILE *f
= NULL
;
1050 if (!isempty(root_dir
))
1051 path
= strjoina(root_dir
, "/", path
);
1054 r
= access(path
, F_OK
) ? -errno
: 0;
1058 fd
= open(path
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
|(allow_symlink
? 0 : O_NOFOLLOW
));
1062 f
= fdopen(fd
, "re");
1068 r
= config_parse(NULL
, path
, f
,
1070 config_item_table_lookup
, items
,
1071 true, true, false, info
);
1076 *also
= !strv_isempty(info
->also
);
1079 (int) strv_length(info
->aliases
) +
1080 (int) strv_length(info
->wanted_by
) +
1081 (int) strv_length(info
->required_by
);
1084 static int unit_file_search(
1086 UnitFileInstallInfo
*info
,
1087 const LookupPaths
*paths
,
1088 const char *root_dir
,
1101 return unit_file_load(c
, info
, info
->path
, root_dir
, allow_symlink
, load
, also
);
1105 STRV_FOREACH(p
, paths
->unit_path
) {
1106 _cleanup_free_
char *path
= NULL
;
1108 path
= strjoin(*p
, "/", info
->name
, NULL
);
1112 r
= unit_file_load(c
, info
, path
, root_dir
, allow_symlink
, load
, also
);
1118 if (r
!= -ENOENT
&& r
!= -ELOOP
)
1122 if (unit_name_is_valid(info
->name
, UNIT_NAME_INSTANCE
)) {
1124 /* Unit file doesn't exist, however instance
1125 * enablement was requested. We will check if it is
1126 * possible to load template unit file. */
1128 _cleanup_free_
char *template = NULL
;
1130 r
= unit_name_template(info
->name
, &template);
1134 STRV_FOREACH(p
, paths
->unit_path
) {
1135 _cleanup_free_
char *path
= NULL
;
1137 path
= strjoin(*p
, "/", template, NULL
);
1141 r
= unit_file_load(c
, info
, path
, root_dir
, allow_symlink
, load
, also
);
1147 if (r
!= -ENOENT
&& r
!= -ELOOP
)
1155 static int unit_file_can_install(
1156 const LookupPaths
*paths
,
1157 const char *root_dir
,
1162 _cleanup_(install_context_done
) InstallContext c
= {};
1163 UnitFileInstallInfo
*i
;
1169 r
= install_info_add_auto(&c
, name
);
1173 assert_se(i
= ordered_hashmap_first(c
.will_install
));
1175 r
= unit_file_search(&c
, i
, paths
, root_dir
, allow_symlink
, true, also
);
1179 (int) strv_length(i
->aliases
) +
1180 (int) strv_length(i
->wanted_by
) +
1181 (int) strv_length(i
->required_by
);
1186 static int create_symlink(
1187 const char *old_path
,
1188 const char *new_path
,
1190 UnitFileChange
**changes
,
1191 unsigned *n_changes
) {
1193 _cleanup_free_
char *dest
= NULL
;
1199 mkdir_parents_label(new_path
, 0755);
1201 if (symlink(old_path
, new_path
) >= 0) {
1202 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_SYMLINK
, new_path
, old_path
);
1206 if (errno
!= EEXIST
)
1209 r
= readlink_and_make_absolute(new_path
, &dest
);
1213 if (path_equal(dest
, old_path
))
1219 r
= symlink_atomic(old_path
, new_path
);
1223 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_UNLINK
, new_path
, NULL
);
1224 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_SYMLINK
, new_path
, old_path
);
1229 static int install_info_symlink_alias(
1230 UnitFileInstallInfo
*i
,
1231 const char *config_path
,
1233 UnitFileChange
**changes
,
1234 unsigned *n_changes
) {
1240 assert(config_path
);
1242 STRV_FOREACH(s
, i
->aliases
) {
1243 _cleanup_free_
char *alias_path
= NULL
, *dst
= NULL
;
1245 q
= install_full_printf(i
, *s
, &dst
);
1249 alias_path
= path_make_absolute(dst
, config_path
);
1253 q
= create_symlink(i
->path
, alias_path
, force
, changes
, n_changes
);
1261 static int install_info_symlink_wants(
1262 UnitFileInstallInfo
*i
,
1263 const char *config_path
,
1267 UnitFileChange
**changes
,
1268 unsigned *n_changes
) {
1270 _cleanup_free_
char *buf
= NULL
;
1276 assert(config_path
);
1278 if (unit_name_is_valid(i
->name
, UNIT_NAME_TEMPLATE
)) {
1280 /* Don't install any symlink if there's no default
1281 * instance configured */
1283 if (!i
->default_instance
)
1286 r
= unit_name_replace_instance(i
->name
, i
->default_instance
, &buf
);
1294 STRV_FOREACH(s
, list
) {
1295 _cleanup_free_
char *path
= NULL
, *dst
= NULL
;
1297 q
= install_full_printf(i
, *s
, &dst
);
1301 if (!unit_name_is_valid(dst
, UNIT_NAME_ANY
)) {
1306 path
= strjoin(config_path
, "/", dst
, suffix
, n
, NULL
);
1310 q
= create_symlink(i
->path
, path
, force
, changes
, n_changes
);
1318 static int install_info_symlink_link(
1319 UnitFileInstallInfo
*i
,
1320 const LookupPaths
*paths
,
1321 const char *config_path
,
1322 const char *root_dir
,
1324 UnitFileChange
**changes
,
1325 unsigned *n_changes
) {
1327 _cleanup_free_
char *path
= NULL
;
1332 assert(config_path
);
1335 r
= in_search_path(i
->path
, paths
->unit_path
);
1339 path
= strjoin(config_path
, "/", i
->name
, NULL
);
1343 return create_symlink(i
->path
, path
, force
, changes
, n_changes
);
1346 static int install_info_apply(
1347 UnitFileInstallInfo
*i
,
1348 const LookupPaths
*paths
,
1349 const char *config_path
,
1350 const char *root_dir
,
1352 UnitFileChange
**changes
,
1353 unsigned *n_changes
) {
1359 assert(config_path
);
1361 r
= install_info_symlink_alias(i
, config_path
, force
, changes
, n_changes
);
1363 q
= install_info_symlink_wants(i
, config_path
, i
->wanted_by
, ".wants/", force
, changes
, n_changes
);
1367 q
= install_info_symlink_wants(i
, config_path
, i
->required_by
, ".requires/", force
, changes
, n_changes
);
1371 q
= install_info_symlink_link(i
, paths
, config_path
, root_dir
, force
, changes
, n_changes
);
1378 static int install_context_apply(
1380 const LookupPaths
*paths
,
1381 const char *config_path
,
1382 const char *root_dir
,
1384 UnitFileChange
**changes
,
1385 unsigned *n_changes
) {
1387 UnitFileInstallInfo
*i
;
1392 assert(config_path
);
1394 if (!ordered_hashmap_isempty(c
->will_install
)) {
1395 r
= ordered_hashmap_ensure_allocated(&c
->have_installed
, &string_hash_ops
);
1399 r
= ordered_hashmap_reserve(c
->have_installed
, ordered_hashmap_size(c
->will_install
));
1405 while ((i
= ordered_hashmap_first(c
->will_install
))) {
1406 assert_se(ordered_hashmap_move_one(c
->have_installed
, c
->will_install
, i
->name
) == 0);
1408 q
= unit_file_search(c
, i
, paths
, root_dir
, false, true, NULL
);
1417 q
= install_info_apply(i
, paths
, config_path
, root_dir
, force
, changes
, n_changes
);
1418 if (r
>= 0 && q
< 0)
1425 static int install_context_mark_for_removal(
1427 const LookupPaths
*paths
,
1428 Set
**remove_symlinks_to
,
1429 const char *config_path
,
1430 const char *root_dir
) {
1432 UnitFileInstallInfo
*i
;
1437 assert(config_path
);
1439 /* Marks all items for removal */
1441 if (!ordered_hashmap_isempty(c
->will_install
)) {
1442 r
= ordered_hashmap_ensure_allocated(&c
->have_installed
, &string_hash_ops
);
1446 r
= ordered_hashmap_reserve(c
->have_installed
, ordered_hashmap_size(c
->will_install
));
1452 while ((i
= ordered_hashmap_first(c
->will_install
))) {
1453 assert_se(ordered_hashmap_move_one(c
->have_installed
, c
->will_install
, i
->name
) == 0);
1455 q
= unit_file_search(c
, i
, paths
, root_dir
, false, true, NULL
);
1466 if (unit_name_is_valid(i
->name
, UNIT_NAME_INSTANCE
)) {
1470 unit_file
= basename(i
->path
);
1472 if (unit_name_is_valid(unit_file
, UNIT_NAME_INSTANCE
))
1473 /* unit file named as instance exists, thus all symlinks
1474 * pointing to it will be removed */
1475 q
= mark_symlink_for_removal(remove_symlinks_to
, i
->name
);
1477 /* does not exist, thus we will mark for removal symlinks
1478 * to template unit file */
1479 q
= mark_symlink_for_removal(remove_symlinks_to
, unit_file
);
1481 /* If i->path is not set, it means that we didn't actually find
1482 * the unit file. But we can still remove symlinks to the
1483 * nonexistent template. */
1484 r
= unit_name_template(i
->name
, &unit_file
);
1488 q
= mark_symlink_for_removal(remove_symlinks_to
, unit_file
);
1492 q
= mark_symlink_for_removal(remove_symlinks_to
, i
->name
);
1494 if (r
>= 0 && q
< 0)
1501 int unit_file_add_dependency(
1502 UnitFileScope scope
,
1504 const char *root_dir
,
1509 UnitFileChange
**changes
,
1510 unsigned *n_changes
) {
1512 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
1513 _cleanup_(install_context_done
) InstallContext c
= {};
1514 _cleanup_free_
char *config_path
= NULL
;
1517 UnitFileInstallInfo
*info
;
1520 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
1522 r
= lookup_paths_init_from_scope(&paths
, scope
, root_dir
);
1526 r
= get_config_path(scope
, runtime
, root_dir
, &config_path
);
1530 STRV_FOREACH(i
, files
) {
1531 UnitFileState state
;
1533 state
= unit_file_get_state(scope
, root_dir
, *i
);
1535 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *i
);
1537 if (state
== UNIT_FILE_MASKED
|| state
== UNIT_FILE_MASKED_RUNTIME
) {
1538 log_error("Failed to enable unit: Unit %s is masked", *i
);
1542 r
= install_info_add_auto(&c
, *i
);
1547 if (!ordered_hashmap_isempty(c
.will_install
)) {
1548 r
= ordered_hashmap_ensure_allocated(&c
.have_installed
, &string_hash_ops
);
1552 r
= ordered_hashmap_reserve(c
.have_installed
, ordered_hashmap_size(c
.will_install
));
1557 while ((info
= ordered_hashmap_first(c
.will_install
))) {
1558 assert_se(ordered_hashmap_move_one(c
.have_installed
, c
.will_install
, info
->name
) == 0);
1560 r
= unit_file_search(&c
, info
, &paths
, root_dir
, false, false, NULL
);
1564 if (dep
== UNIT_WANTS
)
1565 r
= strv_extend(&info
->wanted_by
, target
);
1566 else if (dep
== UNIT_REQUIRES
)
1567 r
= strv_extend(&info
->required_by
, target
);
1574 r
= install_info_apply(info
, &paths
, config_path
, root_dir
, force
, changes
, n_changes
);
1582 int unit_file_enable(
1583 UnitFileScope scope
,
1585 const char *root_dir
,
1588 UnitFileChange
**changes
,
1589 unsigned *n_changes
) {
1591 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
1592 _cleanup_(install_context_done
) InstallContext c
= {};
1594 _cleanup_free_
char *config_path
= NULL
;
1598 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
1600 r
= lookup_paths_init_from_scope(&paths
, scope
, root_dir
);
1604 r
= get_config_path(scope
, runtime
, root_dir
, &config_path
);
1608 STRV_FOREACH(i
, files
) {
1609 UnitFileState state
;
1611 /* We only want to know if this unit is masked, so we ignore
1612 * errors from unit_file_get_state, deferring other checks.
1613 * This allows templated units to be enabled on the fly. */
1614 state
= unit_file_get_state(scope
, root_dir
, *i
);
1615 if (state
== UNIT_FILE_MASKED
|| state
== UNIT_FILE_MASKED_RUNTIME
) {
1616 log_error("Failed to enable unit: Unit %s is masked", *i
);
1620 r
= install_info_add_auto(&c
, *i
);
1625 /* This will return the number of symlink rules that were
1626 supposed to be created, not the ones actually created. This is
1627 useful to determine whether the passed files had any
1628 installation data at all. */
1630 return install_context_apply(&c
, &paths
, config_path
, root_dir
, force
, changes
, n_changes
);
1633 int unit_file_disable(
1634 UnitFileScope scope
,
1636 const char *root_dir
,
1638 UnitFileChange
**changes
,
1639 unsigned *n_changes
) {
1641 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
1642 _cleanup_(install_context_done
) InstallContext c
= {};
1644 _cleanup_free_
char *config_path
= NULL
;
1645 _cleanup_set_free_free_ Set
*remove_symlinks_to
= NULL
;
1649 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
1651 r
= lookup_paths_init_from_scope(&paths
, scope
, root_dir
);
1655 r
= get_config_path(scope
, runtime
, root_dir
, &config_path
);
1659 STRV_FOREACH(i
, files
) {
1660 r
= install_info_add_auto(&c
, *i
);
1665 r
= install_context_mark_for_removal(&c
, &paths
, &remove_symlinks_to
, config_path
, root_dir
);
1667 q
= remove_marked_symlinks(remove_symlinks_to
, config_path
, changes
, n_changes
, files
);
1674 int unit_file_reenable(
1675 UnitFileScope scope
,
1677 const char *root_dir
,
1680 UnitFileChange
**changes
,
1681 unsigned *n_changes
) {
1684 r
= unit_file_disable(scope
, runtime
, root_dir
, files
,
1685 changes
, n_changes
);
1689 return unit_file_enable(scope
, runtime
, root_dir
, files
, force
,
1690 changes
, n_changes
);
1693 int unit_file_set_default(
1694 UnitFileScope scope
,
1695 const char *root_dir
,
1698 UnitFileChange
**changes
,
1699 unsigned *n_changes
) {
1701 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
1702 _cleanup_(install_context_done
) InstallContext c
= {};
1703 _cleanup_free_
char *config_path
= NULL
;
1706 UnitFileInstallInfo
*i
= NULL
;
1709 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
1712 if (unit_name_to_type(file
) != UNIT_TARGET
)
1715 r
= lookup_paths_init_from_scope(&paths
, scope
, root_dir
);
1719 r
= get_config_path(scope
, false, root_dir
, &config_path
);
1723 r
= install_info_add_auto(&c
, file
);
1727 assert_se(i
= ordered_hashmap_first(c
.will_install
));
1729 r
= unit_file_search(&c
, i
, &paths
, root_dir
, false, true, NULL
);
1733 path
= strjoina(config_path
, "/" SPECIAL_DEFAULT_TARGET
);
1735 r
= create_symlink(i
->path
, path
, force
, changes
, n_changes
);
1742 int unit_file_get_default(
1743 UnitFileScope scope
,
1744 const char *root_dir
,
1747 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
1752 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
1755 r
= lookup_paths_init_from_scope(&paths
, scope
, root_dir
);
1759 STRV_FOREACH(p
, paths
.unit_path
) {
1760 _cleanup_free_
char *path
= NULL
, *tmp
= NULL
;
1763 path
= path_join(root_dir
, *p
, SPECIAL_DEFAULT_TARGET
);
1767 r
= readlink_malloc(path
, &tmp
);
1770 else if (r
== -EINVAL
)
1772 n
= strdup(SPECIAL_DEFAULT_TARGET
);
1776 n
= strdup(basename(tmp
));
1788 UnitFileState
unit_file_lookup_state(
1789 UnitFileScope scope
,
1790 const char *root_dir
,
1791 const LookupPaths
*paths
,
1794 UnitFileState state
= _UNIT_FILE_STATE_INVALID
;
1796 _cleanup_free_
char *path
= NULL
;
1801 if (!unit_name_is_valid(name
, UNIT_NAME_ANY
))
1804 STRV_FOREACH(i
, paths
->unit_path
) {
1810 path
= path_join(root_dir
, *i
, name
);
1815 partial
= path
+ strlen(root_dir
);
1820 * Search for a unit file in our default paths, to
1821 * be sure, that there are no broken symlinks.
1823 if (lstat(path
, &st
) < 0) {
1825 if (errno
!= ENOENT
)
1828 if (!unit_name_is_valid(name
, UNIT_NAME_INSTANCE
))
1831 if (!S_ISREG(st
.st_mode
) && !S_ISLNK(st
.st_mode
))
1834 r
= null_or_empty_path(path
);
1835 if (r
< 0 && r
!= -ENOENT
)
1838 state
= path_startswith(*i
, "/run") ? 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
, UNIT_NAME_ANY
))
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
, UNIT_NAME_ANY
))
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
;
2198 if (!de
&& errno
!= 0)
2204 if (hidden_file(de
->d_name
))
2207 if (!unit_name_is_valid(de
->d_name
, UNIT_NAME_ANY
))
2210 if (hashmap_get(h
, de
->d_name
))
2213 dirent_ensure_type(d
, de
);
2215 if (!IN_SET(de
->d_type
, DT_LNK
, DT_REG
))
2218 f
= new0(UnitFileList
, 1);
2222 f
->path
= path_make_absolute(de
->d_name
, units_dir
);
2226 r
= null_or_empty_path(f
->path
);
2227 if (r
< 0 && r
!= -ENOENT
)
2231 path_startswith(*i
, "/run") ?
2232 UNIT_FILE_MASKED_RUNTIME
: UNIT_FILE_MASKED
;
2236 r
= find_symlinks_in_scope(scope
, root_dir
, de
->d_name
, &f
->state
);
2240 f
->state
= UNIT_FILE_ENABLED
;
2244 path
= path_make_absolute(de
->d_name
, *i
);
2248 r
= unit_file_can_install(&paths
, root_dir
, path
, true, &also
);
2249 if (r
== -EINVAL
|| /* Invalid setting? */
2250 r
== -EBADMSG
|| /* Invalid format? */
2251 r
== -ENOENT
/* Included file not found? */)
2252 f
->state
= UNIT_FILE_INVALID
;
2256 f
->state
= UNIT_FILE_DISABLED
;
2258 f
->state
= also
? UNIT_FILE_INDIRECT
: UNIT_FILE_STATIC
;
2261 r
= hashmap_put(h
, basename(f
->path
), f
);
2264 f
= NULL
; /* prevent cleanup */
2271 static const char* const unit_file_state_table
[_UNIT_FILE_STATE_MAX
] = {
2272 [UNIT_FILE_ENABLED
] = "enabled",
2273 [UNIT_FILE_ENABLED_RUNTIME
] = "enabled-runtime",
2274 [UNIT_FILE_LINKED
] = "linked",
2275 [UNIT_FILE_LINKED_RUNTIME
] = "linked-runtime",
2276 [UNIT_FILE_MASKED
] = "masked",
2277 [UNIT_FILE_MASKED_RUNTIME
] = "masked-runtime",
2278 [UNIT_FILE_STATIC
] = "static",
2279 [UNIT_FILE_DISABLED
] = "disabled",
2280 [UNIT_FILE_INDIRECT
] = "indirect",
2281 [UNIT_FILE_INVALID
] = "invalid",
2284 DEFINE_STRING_TABLE_LOOKUP(unit_file_state
, UnitFileState
);
2286 static const char* const unit_file_change_type_table
[_UNIT_FILE_CHANGE_TYPE_MAX
] = {
2287 [UNIT_FILE_SYMLINK
] = "symlink",
2288 [UNIT_FILE_UNLINK
] = "unlink",
2291 DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type
, UnitFileChangeType
);
2293 static const char* const unit_file_preset_mode_table
[_UNIT_FILE_PRESET_MAX
] = {
2294 [UNIT_FILE_PRESET_FULL
] = "full",
2295 [UNIT_FILE_PRESET_ENABLE_ONLY
] = "enable-only",
2296 [UNIT_FILE_PRESET_DISABLE_ONLY
] = "disable-only",
2299 DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode
, UnitFilePresetMode
);