1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty <of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
32 #include "path-util.h"
33 #include "path-lookup.h"
35 #include "unit-name.h"
37 #include "conf-parser.h"
38 #include "conf-files.h"
39 #include "specifier.h"
40 #include "install-printf.h"
44 OrderedHashmap
*will_install
;
45 OrderedHashmap
*have_installed
;
48 static int in_search_path(const char *path
, char **search
) {
49 _cleanup_free_
char *parent
= NULL
;
54 r
= path_get_parent(path
, &parent
);
58 return strv_contains(search
, parent
);
61 static int lookup_paths_init_from_scope(LookupPaths
*paths
,
63 const char *root_dir
) {
66 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
70 return lookup_paths_init(paths
,
71 scope
== UNIT_FILE_SYSTEM
? SYSTEMD_SYSTEM
: SYSTEMD_USER
,
72 scope
== UNIT_FILE_USER
,
77 static int get_config_path(UnitFileScope scope
, bool runtime
, const char *root_dir
, char **ret
) {
82 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
87 case UNIT_FILE_SYSTEM
:
90 p
= path_join(root_dir
, "/run/systemd/system", NULL
);
92 p
= path_join(root_dir
, SYSTEM_CONFIG_UNIT_PATH
, NULL
);
95 case UNIT_FILE_GLOBAL
:
101 p
= strdup("/run/systemd/user");
103 p
= strdup(USER_CONFIG_UNIT_PATH
);
112 r
= user_runtime_dir(&p
);
114 r
= user_config_home(&p
);
117 return r
< 0 ? r
: -ENOENT
;
122 assert_not_reached("Bad scope");
132 static int add_file_change(
133 UnitFileChange
**changes
,
135 UnitFileChangeType type
,
137 const char *source
) {
143 assert(!changes
== !n_changes
);
148 c
= realloc(*changes
, (*n_changes
+ 1) * sizeof(UnitFileChange
));
156 c
[i
].path
= strdup(path
);
160 path_kill_slashes(c
[i
].path
);
163 c
[i
].source
= strdup(source
);
169 path_kill_slashes(c
[i
].path
);
177 static int mark_symlink_for_removal(
178 Set
**remove_symlinks_to
,
186 r
= set_ensure_allocated(remove_symlinks_to
, &string_hash_ops
);
194 path_kill_slashes(n
);
196 r
= set_consume(*remove_symlinks_to
, n
);
198 return r
== -EEXIST
? 0 : r
;
203 static int remove_marked_symlinks_fd(
204 Set
*remove_symlinks_to
,
207 const char *config_path
,
209 UnitFileChange
**changes
,
211 char** instance_whitelist
) {
213 _cleanup_closedir_
DIR *d
= NULL
;
216 assert(remove_symlinks_to
);
235 if (!de
&& errno
!= 0) {
243 if (ignore_file(de
->d_name
))
246 dirent_ensure_type(d
, de
);
248 if (de
->d_type
== DT_DIR
) {
250 _cleanup_free_
char *p
= NULL
;
252 nfd
= openat(fd
, de
->d_name
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
|O_NOFOLLOW
);
262 p
= path_make_absolute(de
->d_name
, path
);
268 /* This will close nfd, regardless whether it succeeds or not */
269 q
= remove_marked_symlinks_fd(remove_symlinks_to
, nfd
, p
, config_path
, deleted
, changes
, n_changes
, instance_whitelist
);
273 } else if (de
->d_type
== DT_LNK
) {
274 _cleanup_free_
char *p
= NULL
, *dest
= NULL
;
278 if (!unit_name_is_valid(de
->d_name
, TEMPLATE_VALID
))
281 if (unit_name_is_instance(de
->d_name
) &&
282 instance_whitelist
&&
283 !strv_contains(instance_whitelist
, de
->d_name
)) {
285 _cleanup_free_
char *w
;
287 /* OK, the file is not listed directly
288 * in the whitelist, so let's check if
289 * the template of it might be
292 w
= unit_name_template(de
->d_name
);
296 if (!strv_contains(instance_whitelist
, w
))
300 p
= path_make_absolute(de
->d_name
, path
);
304 q
= readlink_and_canonicalize(p
, &dest
);
315 set_get(remove_symlinks_to
, dest
) ||
316 set_get(remove_symlinks_to
, basename(dest
));
321 if (unlink(p
) < 0 && errno
!= ENOENT
) {
327 path_kill_slashes(p
);
328 rmdir_parents(p
, config_path
);
329 add_file_change(changes
, n_changes
, UNIT_FILE_UNLINK
, p
, NULL
);
331 if (!set_get(remove_symlinks_to
, p
)) {
333 q
= mark_symlink_for_removal(&remove_symlinks_to
, p
);
346 static int remove_marked_symlinks(
347 Set
*remove_symlinks_to
,
348 const char *config_path
,
349 UnitFileChange
**changes
,
351 char** instance_whitelist
) {
353 _cleanup_close_
int fd
= -1;
359 if (set_size(remove_symlinks_to
) <= 0)
362 fd
= open(config_path
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
|O_NOFOLLOW
);
370 cfd
= fcntl(fd
, F_DUPFD_CLOEXEC
, 3);
376 /* This takes possession of cfd and closes it */
377 q
= remove_marked_symlinks_fd(remove_symlinks_to
, cfd
, config_path
, config_path
, &deleted
, changes
, n_changes
, instance_whitelist
);
385 static int find_symlinks_fd(
389 const char *config_path
,
390 bool *same_name_link
) {
393 _cleanup_closedir_
DIR *d
= NULL
;
399 assert(same_name_link
);
412 if (!de
&& errno
!= 0)
418 if (ignore_file(de
->d_name
))
421 dirent_ensure_type(d
, de
);
423 if (de
->d_type
== DT_DIR
) {
425 _cleanup_free_
char *p
= NULL
;
427 nfd
= openat(fd
, de
->d_name
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
|O_NOFOLLOW
);
437 p
= path_make_absolute(de
->d_name
, path
);
443 /* This will close nfd, regardless whether it succeeds or not */
444 q
= find_symlinks_fd(name
, nfd
, p
, config_path
, same_name_link
);
450 } else if (de
->d_type
== DT_LNK
) {
451 _cleanup_free_
char *p
= NULL
, *dest
= NULL
;
452 bool found_path
, found_dest
, b
= false;
455 /* Acquire symlink name */
456 p
= path_make_absolute(de
->d_name
, path
);
460 /* Acquire symlink destination */
461 q
= readlink_and_canonicalize(p
, &dest
);
471 /* Check if the symlink itself matches what we
473 if (path_is_absolute(name
))
474 found_path
= path_equal(p
, name
);
476 found_path
= streq(de
->d_name
, name
);
478 /* Check if what the symlink points to
479 * matches what we are looking for */
480 if (path_is_absolute(name
))
481 found_dest
= path_equal(dest
, name
);
483 found_dest
= streq(basename(dest
), name
);
485 if (found_path
&& found_dest
) {
486 _cleanup_free_
char *t
= NULL
;
488 /* Filter out same name links in the main
490 t
= path_make_absolute(name
, config_path
);
494 b
= path_equal(t
, p
);
498 *same_name_link
= true;
499 else if (found_path
|| found_dest
)
505 static int find_symlinks(
507 const char *config_path
,
508 bool *same_name_link
) {
514 assert(same_name_link
);
516 fd
= open(config_path
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
|O_NOFOLLOW
);
523 /* This takes possession of fd and closes it */
524 return find_symlinks_fd(name
, fd
, config_path
, config_path
, same_name_link
);
527 static int find_symlinks_in_scope(
529 const char *root_dir
,
531 UnitFileState
*state
) {
534 _cleanup_free_
char *path
= NULL
;
535 bool same_name_link_runtime
= false, same_name_link
= false;
538 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
542 /* First look in runtime config path */
543 r
= get_config_path(scope
, true, root_dir
, &path
);
547 r
= find_symlinks(name
, path
, &same_name_link_runtime
);
551 *state
= UNIT_FILE_ENABLED_RUNTIME
;
555 /* Then look in the normal config path */
556 r
= get_config_path(scope
, false, root_dir
, &path
);
560 r
= find_symlinks(name
, path
, &same_name_link
);
564 *state
= UNIT_FILE_ENABLED
;
568 /* Hmm, we didn't find it, but maybe we found the same name
570 if (same_name_link_runtime
) {
571 *state
= UNIT_FILE_LINKED_RUNTIME
;
573 } else if (same_name_link
) {
574 *state
= UNIT_FILE_LINKED
;
584 const char *root_dir
,
587 UnitFileChange
**changes
,
588 unsigned *n_changes
) {
591 _cleanup_free_
char *prefix
= NULL
;
595 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
597 r
= get_config_path(scope
, runtime
, root_dir
, &prefix
);
601 STRV_FOREACH(i
, files
) {
602 _cleanup_free_
char *path
= NULL
;
604 if (!unit_name_is_valid(*i
, TEMPLATE_VALID
)) {
610 path
= path_make_absolute(*i
, prefix
);
616 if (symlink("/dev/null", path
) >= 0) {
617 add_file_change(changes
, n_changes
, UNIT_FILE_SYMLINK
, path
, "/dev/null");
621 if (errno
== EEXIST
) {
623 if (null_or_empty_path(path
) > 0)
627 if (symlink_atomic("/dev/null", path
) >= 0) {
628 add_file_change(changes
, n_changes
, UNIT_FILE_UNLINK
, path
, NULL
);
629 add_file_change(changes
, n_changes
, UNIT_FILE_SYMLINK
, path
, "/dev/null");
645 int unit_file_unmask(
648 const char *root_dir
,
650 UnitFileChange
**changes
,
651 unsigned *n_changes
) {
653 char **i
, *config_path
= NULL
;
655 Set
*remove_symlinks_to
= NULL
;
658 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
660 r
= get_config_path(scope
, runtime
, root_dir
, &config_path
);
664 STRV_FOREACH(i
, files
) {
667 if (!unit_name_is_valid(*i
, TEMPLATE_VALID
)) {
673 path
= path_make_absolute(*i
, config_path
);
679 q
= null_or_empty_path(path
);
681 if (unlink(path
) >= 0) {
682 mark_symlink_for_removal(&remove_symlinks_to
, path
);
683 add_file_change(changes
, n_changes
, UNIT_FILE_UNLINK
, path
, NULL
);
692 if (q
!= -ENOENT
&& r
== 0)
700 q
= remove_marked_symlinks(remove_symlinks_to
, config_path
, changes
, n_changes
, files
);
704 set_free_free(remove_symlinks_to
);
713 const char *root_dir
,
716 UnitFileChange
**changes
,
717 unsigned *n_changes
) {
719 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
721 _cleanup_free_
char *config_path
= NULL
;
725 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
727 r
= lookup_paths_init_from_scope(&paths
, scope
, root_dir
);
731 r
= get_config_path(scope
, runtime
, root_dir
, &config_path
);
735 STRV_FOREACH(i
, files
) {
736 _cleanup_free_
char *path
= NULL
;
742 if (!path_is_absolute(*i
) ||
743 !unit_name_is_valid(fn
, TEMPLATE_VALID
)) {
749 if (lstat(*i
, &st
) < 0) {
755 if (!S_ISREG(st
.st_mode
)) {
760 q
= in_search_path(*i
, paths
.unit_path
);
767 path
= path_make_absolute(fn
, config_path
);
771 if (symlink(*i
, path
) >= 0) {
772 add_file_change(changes
, n_changes
, UNIT_FILE_SYMLINK
, path
, *i
);
776 if (errno
== EEXIST
) {
777 _cleanup_free_
char *dest
= NULL
;
779 q
= readlink_and_make_absolute(path
, &dest
);
780 if (q
< 0 && errno
!= ENOENT
) {
786 if (q
>= 0 && path_equal(dest
, *i
))
790 if (symlink_atomic(*i
, path
) >= 0) {
791 add_file_change(changes
, n_changes
, UNIT_FILE_UNLINK
, path
, NULL
);
792 add_file_change(changes
, n_changes
, UNIT_FILE_SYMLINK
, path
, *i
);
808 void unit_file_list_free(Hashmap
*h
) {
811 while ((i
= hashmap_steal_first(h
))) {
819 void unit_file_changes_free(UnitFileChange
*changes
, unsigned n_changes
) {
822 assert(changes
|| n_changes
== 0);
827 for (i
= 0; i
< n_changes
; i
++) {
828 free(changes
[i
].path
);
829 free(changes
[i
].source
);
835 static void install_info_free(InstallInfo
*i
) {
840 strv_free(i
->aliases
);
841 strv_free(i
->wanted_by
);
842 strv_free(i
->required_by
);
843 free(i
->default_instance
);
847 static void install_info_hashmap_free(OrderedHashmap
*m
) {
853 while ((i
= ordered_hashmap_steal_first(m
)))
854 install_info_free(i
);
856 ordered_hashmap_free(m
);
859 static void install_context_done(InstallContext
*c
) {
862 install_info_hashmap_free(c
->will_install
);
863 install_info_hashmap_free(c
->have_installed
);
865 c
->will_install
= c
->have_installed
= NULL
;
868 static int install_info_add(
872 InstallInfo
*i
= NULL
;
876 assert(name
|| path
);
879 name
= basename(path
);
881 if (!unit_name_is_valid(name
, TEMPLATE_VALID
))
884 if (ordered_hashmap_get(c
->have_installed
, name
) ||
885 ordered_hashmap_get(c
->will_install
, name
))
888 r
= ordered_hashmap_ensure_allocated(&c
->will_install
, &string_hash_ops
);
892 i
= new0(InstallInfo
, 1);
896 i
->name
= strdup(name
);
903 i
->path
= strdup(path
);
910 r
= ordered_hashmap_put(c
->will_install
, i
->name
, i
);
918 install_info_free(i
);
923 static int install_info_add_auto(
925 const char *name_or_path
) {
928 assert(name_or_path
);
930 if (path_is_absolute(name_or_path
))
931 return install_info_add(c
, NULL
, name_or_path
);
933 return install_info_add(c
, name_or_path
, NULL
);
936 static int config_parse_also(
938 const char *filename
,
941 unsigned section_line
,
949 const char *word
, *state
;
950 InstallContext
*c
= data
;
956 FOREACH_WORD_QUOTED(word
, l
, rvalue
, state
) {
957 _cleanup_free_
char *n
;
960 n
= strndup(word
, l
);
964 r
= install_info_add(c
, n
, NULL
);
969 log_syntax(unit
, LOG_ERR
, filename
, line
, EINVAL
,
970 "Trailing garbage, ignoring.");
975 static int config_parse_user(
977 const char *filename
,
980 unsigned section_line
,
987 InstallInfo
*i
= data
;
995 r
= install_full_printf(i
, rvalue
, &printed
);
1005 static int config_parse_default_instance(
1007 const char *filename
,
1009 const char *section
,
1010 unsigned section_line
,
1017 InstallInfo
*i
= data
;
1025 r
= install_full_printf(i
, rvalue
, &printed
);
1029 if (!unit_instance_is_valid(printed
)) {
1034 free(i
->default_instance
);
1035 i
->default_instance
= printed
;
1040 static int unit_file_load(
1044 const char *root_dir
,
1048 const ConfigTableItem items
[] = {
1049 { "Install", "Alias", config_parse_strv
, 0, &info
->aliases
},
1050 { "Install", "WantedBy", config_parse_strv
, 0, &info
->wanted_by
},
1051 { "Install", "RequiredBy", config_parse_strv
, 0, &info
->required_by
},
1052 { "Install", "DefaultInstance", config_parse_default_instance
, 0, info
},
1053 { "Install", "Also", config_parse_also
, 0, c
},
1054 { "Exec", "User", config_parse_user
, 0, info
},
1058 _cleanup_fclose_
FILE *f
= NULL
;
1065 if (!isempty(root_dir
))
1066 path
= strappenda(root_dir
, "/", path
);
1069 r
= access(path
, F_OK
) ? -errno
: 0;
1073 fd
= open(path
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
|(allow_symlink
? 0 : O_NOFOLLOW
));
1077 f
= fdopen(fd
, "re");
1083 r
= config_parse(NULL
, path
, f
,
1085 config_item_table_lookup
, items
,
1086 true, true, false, info
);
1091 (int) strv_length(info
->aliases
) +
1092 (int) strv_length(info
->wanted_by
) +
1093 (int) strv_length(info
->required_by
);
1096 static int unit_file_search(
1100 const char *root_dir
,
1112 return unit_file_load(c
, info
, info
->path
, root_dir
, allow_symlink
, load
);
1116 STRV_FOREACH(p
, paths
->unit_path
) {
1117 _cleanup_free_
char *path
= NULL
;
1119 path
= strjoin(*p
, "/", info
->name
, NULL
);
1123 r
= unit_file_load(c
, info
, path
, root_dir
, allow_symlink
, load
);
1129 if (r
!= -ENOENT
&& r
!= -ELOOP
)
1133 if (unit_name_is_instance(info
->name
)) {
1135 /* Unit file doesn't exist, however instance
1136 * enablement was requested. We will check if it is
1137 * possible to load template unit file. */
1139 _cleanup_free_
char *template = NULL
;
1141 template = unit_name_template(info
->name
);
1145 STRV_FOREACH(p
, paths
->unit_path
) {
1146 _cleanup_free_
char *path
= NULL
;
1148 path
= strjoin(*p
, "/", template, NULL
);
1152 r
= unit_file_load(c
, info
, path
, root_dir
, allow_symlink
, load
);
1158 if (r
!= -ENOENT
&& r
!= -ELOOP
)
1166 static int unit_file_can_install(
1168 const char *root_dir
,
1170 bool allow_symlink
) {
1172 _cleanup_(install_context_done
) InstallContext c
= {};
1179 r
= install_info_add_auto(&c
, name
);
1183 assert_se(i
= ordered_hashmap_first(c
.will_install
));
1185 r
= unit_file_search(&c
, i
, paths
, root_dir
, allow_symlink
, true);
1189 (int) strv_length(i
->aliases
) +
1190 (int) strv_length(i
->wanted_by
) +
1191 (int) strv_length(i
->required_by
);
1196 static int create_symlink(
1197 const char *old_path
,
1198 const char *new_path
,
1200 UnitFileChange
**changes
,
1201 unsigned *n_changes
) {
1203 _cleanup_free_
char *dest
= NULL
;
1209 mkdir_parents_label(new_path
, 0755);
1211 if (symlink(old_path
, new_path
) >= 0) {
1212 add_file_change(changes
, n_changes
, UNIT_FILE_SYMLINK
, new_path
, old_path
);
1216 if (errno
!= EEXIST
)
1219 r
= readlink_and_make_absolute(new_path
, &dest
);
1223 if (path_equal(dest
, old_path
))
1229 r
= symlink_atomic(old_path
, new_path
);
1233 add_file_change(changes
, n_changes
, UNIT_FILE_UNLINK
, new_path
, NULL
);
1234 add_file_change(changes
, n_changes
, UNIT_FILE_SYMLINK
, new_path
, old_path
);
1239 static int install_info_symlink_alias(
1241 const char *config_path
,
1243 UnitFileChange
**changes
,
1244 unsigned *n_changes
) {
1250 assert(config_path
);
1252 STRV_FOREACH(s
, i
->aliases
) {
1253 _cleanup_free_
char *alias_path
= NULL
, *dst
= NULL
;
1255 q
= install_full_printf(i
, *s
, &dst
);
1259 alias_path
= path_make_absolute(dst
, config_path
);
1263 q
= create_symlink(i
->path
, alias_path
, force
, changes
, n_changes
);
1271 static int install_info_symlink_wants(
1273 const char *config_path
,
1277 UnitFileChange
**changes
,
1278 unsigned *n_changes
) {
1280 _cleanup_free_
char *buf
= NULL
;
1286 assert(config_path
);
1288 if (unit_name_is_template(i
->name
)) {
1290 /* Don't install any symlink if there's no default
1291 * instance configured */
1293 if (!i
->default_instance
)
1296 buf
= unit_name_replace_instance(i
->name
, i
->default_instance
);
1304 STRV_FOREACH(s
, list
) {
1305 _cleanup_free_
char *path
= NULL
, *dst
= NULL
;
1307 q
= install_full_printf(i
, *s
, &dst
);
1311 if (!unit_name_is_valid(dst
, TEMPLATE_VALID
)) {
1316 path
= strjoin(config_path
, "/", dst
, suffix
, n
, NULL
);
1320 q
= create_symlink(i
->path
, path
, force
, changes
, n_changes
);
1328 static int install_info_symlink_link(
1331 const char *config_path
,
1332 const char *root_dir
,
1334 UnitFileChange
**changes
,
1335 unsigned *n_changes
) {
1337 _cleanup_free_
char *path
= NULL
;
1342 assert(config_path
);
1345 r
= in_search_path(i
->path
, paths
->unit_path
);
1349 path
= strjoin(config_path
, "/", i
->name
, NULL
);
1353 return create_symlink(i
->path
, path
, force
, changes
, n_changes
);
1356 static int install_info_apply(
1359 const char *config_path
,
1360 const char *root_dir
,
1362 UnitFileChange
**changes
,
1363 unsigned *n_changes
) {
1369 assert(config_path
);
1371 r
= install_info_symlink_alias(i
, config_path
, force
, changes
, n_changes
);
1373 q
= install_info_symlink_wants(i
, config_path
, i
->wanted_by
, ".wants/", force
, changes
, n_changes
);
1377 q
= install_info_symlink_wants(i
, config_path
, i
->required_by
, ".requires/", force
, changes
, n_changes
);
1381 q
= install_info_symlink_link(i
, paths
, config_path
, root_dir
, force
, changes
, n_changes
);
1388 static int install_context_apply(
1391 const char *config_path
,
1392 const char *root_dir
,
1394 UnitFileChange
**changes
,
1395 unsigned *n_changes
) {
1402 assert(config_path
);
1404 if (!ordered_hashmap_isempty(c
->will_install
)) {
1405 r
= ordered_hashmap_ensure_allocated(&c
->have_installed
, &string_hash_ops
);
1409 r
= ordered_hashmap_reserve(c
->have_installed
, ordered_hashmap_size(c
->will_install
));
1415 while ((i
= ordered_hashmap_first(c
->will_install
))) {
1416 assert_se(ordered_hashmap_move_one(c
->have_installed
, c
->will_install
, i
->name
) == 0);
1418 q
= unit_file_search(c
, i
, paths
, root_dir
, false, true);
1427 q
= install_info_apply(i
, paths
, config_path
, root_dir
, force
, changes
, n_changes
);
1428 if (r
>= 0 && q
< 0)
1435 static int install_context_mark_for_removal(
1438 Set
**remove_symlinks_to
,
1439 const char *config_path
,
1440 const char *root_dir
) {
1447 assert(config_path
);
1449 /* Marks all items for removal */
1451 if (!ordered_hashmap_isempty(c
->will_install
)) {
1452 r
= ordered_hashmap_ensure_allocated(&c
->have_installed
, &string_hash_ops
);
1456 r
= ordered_hashmap_reserve(c
->have_installed
, ordered_hashmap_size(c
->will_install
));
1462 while ((i
= ordered_hashmap_first(c
->will_install
))) {
1463 assert_se(ordered_hashmap_move_one(c
->have_installed
, c
->will_install
, i
->name
) == 0);
1465 q
= unit_file_search(c
, i
, paths
, root_dir
, false, true);
1476 if (unit_name_is_instance(i
->name
)) {
1480 unit_file
= basename(i
->path
);
1482 if (unit_name_is_instance(unit_file
))
1483 /* unit file named as instance exists, thus all symlinks
1484 * pointing to it will be removed */
1485 q
= mark_symlink_for_removal(remove_symlinks_to
, i
->name
);
1487 /* does not exist, thus we will mark for removal symlinks
1488 * to template unit file */
1489 q
= mark_symlink_for_removal(remove_symlinks_to
, unit_file
);
1491 /* If i->path is not set, it means that we didn't actually find
1492 * the unit file. But we can still remove symlinks to the
1493 * nonexistent template. */
1494 unit_file
= unit_name_template(i
->name
);
1498 q
= mark_symlink_for_removal(remove_symlinks_to
, unit_file
);
1502 q
= mark_symlink_for_removal(remove_symlinks_to
, i
->name
);
1504 if (r
>= 0 && q
< 0)
1511 int unit_file_add_dependency(
1512 UnitFileScope scope
,
1514 const char *root_dir
,
1519 UnitFileChange
**changes
,
1520 unsigned *n_changes
) {
1522 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
1523 _cleanup_(install_context_done
) InstallContext c
= {};
1524 _cleanup_free_
char *config_path
= NULL
;
1530 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
1532 r
= lookup_paths_init_from_scope(&paths
, scope
, root_dir
);
1536 r
= get_config_path(scope
, runtime
, root_dir
, &config_path
);
1540 STRV_FOREACH(i
, files
) {
1541 UnitFileState state
;
1543 state
= unit_file_get_state(scope
, root_dir
, *i
);
1545 log_error("Failed to get unit file state for %s: %s", *i
, strerror(-state
));
1549 if (state
== UNIT_FILE_MASKED
|| state
== UNIT_FILE_MASKED_RUNTIME
) {
1550 log_error("Failed to enable unit: Unit %s is masked", *i
);
1554 r
= install_info_add_auto(&c
, *i
);
1559 if (!ordered_hashmap_isempty(c
.will_install
)) {
1560 r
= ordered_hashmap_ensure_allocated(&c
.have_installed
, &string_hash_ops
);
1564 r
= ordered_hashmap_reserve(c
.have_installed
, ordered_hashmap_size(c
.will_install
));
1569 while ((info
= ordered_hashmap_first(c
.will_install
))) {
1570 assert_se(ordered_hashmap_move_one(c
.have_installed
, c
.will_install
, info
->name
) == 0);
1572 r
= unit_file_search(&c
, info
, &paths
, root_dir
, false, false);
1576 if (dep
== UNIT_WANTS
)
1577 r
= strv_extend(&info
->wanted_by
, target
);
1578 else if (dep
== UNIT_REQUIRES
)
1579 r
= strv_extend(&info
->required_by
, target
);
1586 r
= install_info_apply(info
, &paths
, config_path
, root_dir
, force
, changes
, n_changes
);
1594 int unit_file_enable(
1595 UnitFileScope scope
,
1597 const char *root_dir
,
1600 UnitFileChange
**changes
,
1601 unsigned *n_changes
) {
1603 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
1604 _cleanup_(install_context_done
) InstallContext c
= {};
1606 _cleanup_free_
char *config_path
= NULL
;
1610 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
1612 r
= lookup_paths_init_from_scope(&paths
, scope
, root_dir
);
1616 r
= get_config_path(scope
, runtime
, root_dir
, &config_path
);
1620 STRV_FOREACH(i
, files
) {
1621 UnitFileState state
;
1623 state
= unit_file_get_state(scope
, root_dir
, *i
);
1625 log_error("Failed to get unit file state for %s: %s", *i
, strerror(-state
));
1629 if (state
== UNIT_FILE_MASKED
|| state
== UNIT_FILE_MASKED_RUNTIME
) {
1630 log_error("Failed to enable unit: Unit %s is masked", *i
);
1634 r
= install_info_add_auto(&c
, *i
);
1639 /* This will return the number of symlink rules that were
1640 supposed to be created, not the ones actually created. This is
1641 useful to determine whether the passed files had any
1642 installation data at all. */
1644 return install_context_apply(&c
, &paths
, config_path
, root_dir
, force
, changes
, n_changes
);
1647 int unit_file_disable(
1648 UnitFileScope scope
,
1650 const char *root_dir
,
1652 UnitFileChange
**changes
,
1653 unsigned *n_changes
) {
1655 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
1656 _cleanup_(install_context_done
) InstallContext c
= {};
1658 _cleanup_free_
char *config_path
= NULL
;
1659 _cleanup_set_free_free_ Set
*remove_symlinks_to
= NULL
;
1663 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
1665 r
= lookup_paths_init_from_scope(&paths
, scope
, root_dir
);
1669 r
= get_config_path(scope
, runtime
, root_dir
, &config_path
);
1673 STRV_FOREACH(i
, files
) {
1674 r
= install_info_add_auto(&c
, *i
);
1679 r
= install_context_mark_for_removal(&c
, &paths
, &remove_symlinks_to
, config_path
, root_dir
);
1681 q
= remove_marked_symlinks(remove_symlinks_to
, config_path
, changes
, n_changes
, files
);
1688 int unit_file_reenable(
1689 UnitFileScope scope
,
1691 const char *root_dir
,
1694 UnitFileChange
**changes
,
1695 unsigned *n_changes
) {
1698 r
= unit_file_disable(scope
, runtime
, root_dir
, files
,
1699 changes
, n_changes
);
1703 return unit_file_enable(scope
, runtime
, root_dir
, files
, force
,
1704 changes
, n_changes
);
1707 int unit_file_set_default(
1708 UnitFileScope scope
,
1709 const char *root_dir
,
1712 UnitFileChange
**changes
,
1713 unsigned *n_changes
) {
1715 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
1716 _cleanup_(install_context_done
) InstallContext c
= {};
1717 _cleanup_free_
char *config_path
= NULL
;
1720 InstallInfo
*i
= NULL
;
1723 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
1726 if (unit_name_to_type(file
) != UNIT_TARGET
)
1729 r
= lookup_paths_init_from_scope(&paths
, scope
, root_dir
);
1733 r
= get_config_path(scope
, false, root_dir
, &config_path
);
1737 r
= install_info_add_auto(&c
, file
);
1741 assert_se(i
= ordered_hashmap_first(c
.will_install
));
1743 r
= unit_file_search(&c
, i
, &paths
, root_dir
, false, true);
1747 path
= strappenda(config_path
, "/" SPECIAL_DEFAULT_TARGET
);
1749 r
= create_symlink(i
->path
, path
, force
, changes
, n_changes
);
1756 int unit_file_get_default(
1757 UnitFileScope scope
,
1758 const char *root_dir
,
1761 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
1766 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
1769 r
= lookup_paths_init_from_scope(&paths
, scope
, root_dir
);
1773 STRV_FOREACH(p
, paths
.unit_path
) {
1774 _cleanup_free_
char *path
= NULL
, *tmp
= NULL
;
1777 path
= path_join(root_dir
, *p
, SPECIAL_DEFAULT_TARGET
);
1781 r
= readlink_malloc(path
, &tmp
);
1784 else if (r
== -EINVAL
)
1786 n
= strdup(SPECIAL_DEFAULT_TARGET
);
1790 n
= strdup(basename(tmp
));
1802 UnitFileState
unit_file_get_state(
1803 UnitFileScope scope
,
1804 const char *root_dir
,
1807 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
1808 UnitFileState state
= _UNIT_FILE_STATE_INVALID
;
1810 _cleanup_free_
char *path
= NULL
;
1814 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
1817 if (root_dir
&& scope
!= UNIT_FILE_SYSTEM
)
1820 if (!unit_name_is_valid(name
, TEMPLATE_VALID
))
1823 r
= lookup_paths_init_from_scope(&paths
, scope
, root_dir
);
1827 STRV_FOREACH(i
, paths
.unit_path
) {
1834 path
= path_join(root_dir
, *i
, name
);
1839 partial
= path
+ strlen(root_dir
);
1844 * Search for a unit file in our default paths, to
1845 * be sure, that there are no broken symlinks.
1847 if (lstat(path
, &st
) < 0) {
1849 if (errno
!= ENOENT
)
1852 if (!unit_name_is_instance(name
))
1855 if (!S_ISREG(st
.st_mode
) && !S_ISLNK(st
.st_mode
))
1858 r
= null_or_empty_path(path
);
1859 if (r
< 0 && r
!= -ENOENT
)
1862 state
= path_startswith(*i
, "/run") ?
1863 UNIT_FILE_MASKED_RUNTIME
: UNIT_FILE_MASKED
;
1868 r
= find_symlinks_in_scope(scope
, root_dir
, name
, &state
);
1874 r
= unit_file_can_install(&paths
, root_dir
, partial
, true);
1875 if (r
< 0 && errno
!= ENOENT
)
1878 return UNIT_FILE_DISABLED
;
1880 return UNIT_FILE_STATIC
;
1883 return r
< 0 ? r
: state
;
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 (ignore_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 (ignore_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);
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_INVALID
] = "invalid",
2282 DEFINE_STRING_TABLE_LOOKUP(unit_file_state
, UnitFileState
);
2284 static const char* const unit_file_change_type_table
[_UNIT_FILE_CHANGE_TYPE_MAX
] = {
2285 [UNIT_FILE_SYMLINK
] = "symlink",
2286 [UNIT_FILE_UNLINK
] = "unlink",
2289 DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type
, UnitFileChangeType
);
2291 static const char* const unit_file_preset_mode_table
[_UNIT_FILE_PRESET_MAX
] = {
2292 [UNIT_FILE_PRESET_FULL
] = "full",
2293 [UNIT_FILE_PRESET_ENABLE_ONLY
] = "enable-only",
2294 [UNIT_FILE_PRESET_DISABLE_ONLY
] = "disable-only",
2297 DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode
, UnitFilePresetMode
);