2 This file is part of systemd.
4 Copyright 2011 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty <of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
32 #include "alloc-util.h"
33 #include "conf-files.h"
34 #include "conf-parser.h"
35 #include "dirent-util.h"
36 #include "extract-word.h"
41 #include "install-printf.h"
43 #include "locale-util.h"
47 #include "path-lookup.h"
48 #include "path-util.h"
52 #include "stat-util.h"
53 #include "string-table.h"
54 #include "string-util.h"
56 #include "unit-name.h"
58 #define UNIT_FILE_FOLLOW_SYMLINK_MAX 64
60 typedef enum SearchFlags
{
62 SEARCH_FOLLOW_CONFIG_SYMLINKS
= 2,
66 OrderedHashmap
*will_process
;
67 OrderedHashmap
*have_processed
;
86 static inline void presets_freep(Presets
*p
) {
92 for (i
= 0; i
< p
->n_rules
; i
++)
93 free(p
->rules
[i
].pattern
);
99 static int unit_file_lookup_state(UnitFileScope scope
, const LookupPaths
*paths
, const char *name
, UnitFileState
*ret
);
101 bool unit_type_may_alias(UnitType type
) {
111 bool unit_type_may_template(UnitType type
) {
120 static const char *unit_file_type_table
[_UNIT_FILE_TYPE_MAX
] = {
121 [UNIT_FILE_TYPE_REGULAR
] = "regular",
122 [UNIT_FILE_TYPE_SYMLINK
] = "symlink",
123 [UNIT_FILE_TYPE_MASKED
] = "masked",
126 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(unit_file_type
, UnitFileType
);
128 static int in_search_path(const LookupPaths
*p
, const char *path
) {
129 _cleanup_free_
char *parent
= NULL
;
134 parent
= dirname_malloc(path
);
138 STRV_FOREACH(i
, p
->search_path
)
139 if (path_equal(parent
, *i
))
145 static const char* skip_root(const LookupPaths
*p
, const char *path
) {
154 e
= path_startswith(path
, p
->root_dir
);
158 /* Make sure the returned path starts with a slash */
160 if (e
== path
|| e
[-1] != '/')
169 static int path_is_generator(const LookupPaths
*p
, const char *path
) {
170 _cleanup_free_
char *parent
= NULL
;
175 parent
= dirname_malloc(path
);
179 return path_equal_ptr(parent
, p
->generator
) ||
180 path_equal_ptr(parent
, p
->generator_early
) ||
181 path_equal_ptr(parent
, p
->generator_late
);
184 static int path_is_transient(const LookupPaths
*p
, const char *path
) {
185 _cleanup_free_
char *parent
= NULL
;
190 parent
= dirname_malloc(path
);
194 return path_equal_ptr(parent
, p
->transient
);
197 static int path_is_control(const LookupPaths
*p
, const char *path
) {
198 _cleanup_free_
char *parent
= NULL
;
203 parent
= dirname_malloc(path
);
207 return path_equal_ptr(parent
, p
->persistent_control
) ||
208 path_equal_ptr(parent
, p
->runtime_control
);
211 static int path_is_config(const LookupPaths
*p
, const char *path
) {
212 _cleanup_free_
char *parent
= NULL
;
217 /* Note that we do *not* have generic checks for /etc or /run in place, since with
218 * them we couldn't discern configuration from transient or generated units */
220 parent
= dirname_malloc(path
);
224 return path_equal_ptr(parent
, p
->persistent_config
) ||
225 path_equal_ptr(parent
, p
->runtime_config
);
228 static int path_is_runtime(const LookupPaths
*p
, const char *path
) {
229 _cleanup_free_
char *parent
= NULL
;
235 /* Everything in /run is considered runtime. On top of that we also add
236 * explicit checks for the various runtime directories, as safety net. */
238 rpath
= skip_root(p
, path
);
239 if (rpath
&& path_startswith(rpath
, "/run"))
242 parent
= dirname_malloc(path
);
246 return path_equal_ptr(parent
, p
->runtime_config
) ||
247 path_equal_ptr(parent
, p
->generator
) ||
248 path_equal_ptr(parent
, p
->generator_early
) ||
249 path_equal_ptr(parent
, p
->generator_late
) ||
250 path_equal_ptr(parent
, p
->transient
) ||
251 path_equal_ptr(parent
, p
->runtime_control
);
254 static int path_is_vendor(const LookupPaths
*p
, const char *path
) {
260 rpath
= skip_root(p
, path
);
264 if (path_startswith(rpath
, "/usr"))
267 #ifdef HAVE_SPLIT_USR
268 if (path_startswith(rpath
, "/lib"))
272 return path_equal(rpath
, SYSTEM_DATA_UNIT_PATH
);
275 int unit_file_changes_add(
276 UnitFileChange
**changes
,
278 UnitFileChangeType type
,
280 const char *source
) {
282 _cleanup_free_
char *p
= NULL
, *s
= NULL
;
286 assert(!changes
== !n_changes
);
291 c
= realloc(*changes
, (*n_changes
+ 1) * sizeof(UnitFileChange
));
300 if (!p
|| (source
&& !s
))
303 path_kill_slashes(p
);
305 path_kill_slashes(s
);
307 c
[*n_changes
] = (UnitFileChange
) { type
, p
, s
};
313 void unit_file_changes_free(UnitFileChange
*changes
, unsigned n_changes
) {
316 assert(changes
|| n_changes
== 0);
318 for (i
= 0; i
< n_changes
; i
++) {
319 free(changes
[i
].path
);
320 free(changes
[i
].source
);
326 void unit_file_dump_changes(int r
, const char *verb
, const UnitFileChange
*changes
, unsigned n_changes
, bool quiet
) {
330 assert(changes
|| n_changes
== 0);
331 /* If verb is not specified, errors are not allowed! */
332 assert(verb
|| r
>= 0);
334 for (i
= 0; i
< n_changes
; i
++) {
335 assert(verb
|| changes
[i
].type
>= 0);
337 switch(changes
[i
].type
) {
338 case UNIT_FILE_SYMLINK
:
340 log_info("Created symlink %s %s %s.",
342 special_glyph(ARROW
),
345 case UNIT_FILE_UNLINK
:
347 log_info("Removed %s.", changes
[i
].path
);
349 case UNIT_FILE_IS_MASKED
:
351 log_info("Unit %s is masked, ignoring.", changes
[i
].path
);
353 case UNIT_FILE_IS_DANGLING
:
355 log_info("Unit %s is an alias to a unit that is not present, ignoring.",
359 if (changes
[i
].source
)
360 log_error_errno(changes
[i
].type
,
361 "Failed to %s unit, file %s already exists and is a symlink to %s.",
362 verb
, changes
[i
].path
, changes
[i
].source
);
364 log_error_errno(changes
[i
].type
,
365 "Failed to %s unit, file %s already exists.",
366 verb
, changes
[i
].path
);
370 log_error_errno(changes
[i
].type
, "Failed to %s unit, unit %s is masked.",
371 verb
, changes
[i
].path
);
375 log_error_errno(changes
[i
].type
, "Failed to %s unit, unit %s is transient or generated.",
376 verb
, changes
[i
].path
);
380 log_error_errno(changes
[i
].type
, "Failed to %s unit, refusing to operate on linked unit file %s",
381 verb
, changes
[i
].path
);
385 assert(changes
[i
].type
< 0);
386 log_error_errno(changes
[i
].type
, "Failed to %s unit, file %s: %m.",
387 verb
, changes
[i
].path
);
392 if (r
< 0 && !logged
)
393 log_error_errno(r
, "Failed to %s: %m.", verb
);
397 * Checks if two paths or symlinks from wd are the same, when root is the root of the filesystem.
398 * wc should be the full path in the host file system.
400 static bool chroot_symlinks_same(const char *root
, const char *wd
, const char *a
, const char *b
) {
401 assert(path_is_absolute(wd
));
403 /* This will give incorrect results if the paths are relative and go outside
404 * of the chroot. False negatives are possible. */
409 a
= strjoina(path_is_absolute(a
) ? root
: wd
, "/", a
);
410 b
= strjoina(path_is_absolute(b
) ? root
: wd
, "/", b
);
411 return path_equal_or_files_same(a
, b
);
414 static int create_symlink(
415 const LookupPaths
*paths
,
416 const char *old_path
,
417 const char *new_path
,
419 UnitFileChange
**changes
,
420 unsigned *n_changes
) {
422 _cleanup_free_
char *dest
= NULL
, *dirname
= NULL
;
429 rp
= skip_root(paths
, old_path
);
433 /* Actually create a symlink, and remember that we did. Is
434 * smart enough to check if there's already a valid symlink in
437 * Returns 1 if a symlink was created or already exists and points to
438 * the right place, or negative on error.
441 mkdir_parents_label(new_path
, 0755);
443 if (symlink(old_path
, new_path
) >= 0) {
444 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_SYMLINK
, new_path
, old_path
);
448 if (errno
!= EEXIST
) {
449 unit_file_changes_add(changes
, n_changes
, -errno
, new_path
, NULL
);
453 r
= readlink_malloc(new_path
, &dest
);
455 /* translate EINVAL (non-symlink exists) to EEXIST */
459 unit_file_changes_add(changes
, n_changes
, r
, new_path
, NULL
);
463 dirname
= dirname_malloc(new_path
);
467 if (chroot_symlinks_same(paths
->root_dir
, dirname
, dest
, old_path
))
471 unit_file_changes_add(changes
, n_changes
, -EEXIST
, new_path
, dest
);
475 r
= symlink_atomic(old_path
, new_path
);
477 unit_file_changes_add(changes
, n_changes
, r
, new_path
, NULL
);
481 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_UNLINK
, new_path
, NULL
);
482 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_SYMLINK
, new_path
, old_path
);
487 static int mark_symlink_for_removal(
488 Set
**remove_symlinks_to
,
496 r
= set_ensure_allocated(remove_symlinks_to
, &string_hash_ops
);
504 path_kill_slashes(n
);
506 r
= set_consume(*remove_symlinks_to
, n
);
515 static int remove_marked_symlinks_fd(
516 Set
*remove_symlinks_to
,
519 const char *config_path
,
520 const LookupPaths
*lp
,
522 UnitFileChange
**changes
,
523 unsigned *n_changes
) {
525 _cleanup_closedir_
DIR *d
= NULL
;
529 assert(remove_symlinks_to
);
544 FOREACH_DIRENT(de
, d
, return -errno
) {
546 dirent_ensure_type(d
, de
);
548 if (de
->d_type
== DT_DIR
) {
549 _cleanup_free_
char *p
= NULL
;
552 nfd
= openat(fd
, de
->d_name
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
|O_NOFOLLOW
);
562 p
= path_make_absolute(de
->d_name
, path
);
568 /* This will close nfd, regardless whether it succeeds or not */
569 q
= remove_marked_symlinks_fd(remove_symlinks_to
, nfd
, p
, config_path
, lp
, restart
, changes
, n_changes
);
573 } else if (de
->d_type
== DT_LNK
) {
574 _cleanup_free_
char *p
= NULL
, *dest
= NULL
;
579 if (!unit_name_is_valid(de
->d_name
, UNIT_NAME_ANY
))
582 p
= path_make_absolute(de
->d_name
, path
);
585 path_kill_slashes(p
);
587 q
= readlink_malloc(p
, &dest
);
596 /* We remove all links pointing to a file or path that is marked, as well as all files sharing
597 * the same name as a file that is marked. */
599 found
= set_contains(remove_symlinks_to
, dest
) ||
600 set_contains(remove_symlinks_to
, basename(dest
)) ||
601 set_contains(remove_symlinks_to
, de
->d_name
);
606 if (unlinkat(fd
, de
->d_name
, 0) < 0 && errno
!= ENOENT
) {
609 unit_file_changes_add(changes
, n_changes
, -errno
, p
, NULL
);
613 (void) rmdir_parents(p
, config_path
);
615 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_UNLINK
, p
, NULL
);
617 /* Now, remember the full path (but with the root prefix removed) of
618 * the symlink we just removed, and remove any symlinks to it, too. */
620 rp
= skip_root(lp
, p
);
621 q
= mark_symlink_for_removal(&remove_symlinks_to
, rp
?: p
);
632 static int remove_marked_symlinks(
633 Set
*remove_symlinks_to
,
634 const char *config_path
,
635 const LookupPaths
*lp
,
636 UnitFileChange
**changes
,
637 unsigned *n_changes
) {
639 _cleanup_close_
int fd
= -1;
646 if (set_size(remove_symlinks_to
) <= 0)
649 fd
= open(config_path
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
);
651 return errno
== ENOENT
? 0 : -errno
;
657 cfd
= fcntl(fd
, F_DUPFD_CLOEXEC
, 3);
661 /* This takes possession of cfd and closes it */
662 q
= remove_marked_symlinks_fd(remove_symlinks_to
, cfd
, config_path
, config_path
, lp
, &restart
, changes
, n_changes
);
670 static int find_symlinks_fd(
671 const char *root_dir
,
675 const char *config_path
,
676 const LookupPaths
*lp
,
677 bool *same_name_link
) {
679 _cleanup_closedir_
DIR *d
= NULL
;
688 assert(same_name_link
);
696 FOREACH_DIRENT(de
, d
, return -errno
) {
698 dirent_ensure_type(d
, de
);
700 if (de
->d_type
== DT_DIR
) {
701 _cleanup_free_
char *p
= NULL
;
704 nfd
= openat(fd
, de
->d_name
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
|O_NOFOLLOW
);
714 p
= path_make_absolute(de
->d_name
, path
);
720 /* This will close nfd, regardless whether it succeeds or not */
721 q
= find_symlinks_fd(root_dir
, name
, nfd
, p
, config_path
, lp
, same_name_link
);
727 } else if (de
->d_type
== DT_LNK
) {
728 _cleanup_free_
char *p
= NULL
, *dest
= NULL
;
729 bool found_path
, found_dest
, b
= false;
732 /* Acquire symlink name */
733 p
= path_make_absolute(de
->d_name
, path
);
737 /* Acquire symlink destination */
738 q
= readlink_malloc(p
, &dest
);
748 if (!path_is_absolute(dest
)) {
751 x
= prefix_root(root_dir
, dest
);
759 /* Check if the symlink itself matches what we
761 if (path_is_absolute(name
))
762 found_path
= path_equal(p
, name
);
764 found_path
= streq(de
->d_name
, name
);
766 /* Check if what the symlink points to
767 * matches what we are looking for */
768 if (path_is_absolute(name
))
769 found_dest
= path_equal(dest
, name
);
771 found_dest
= streq(basename(dest
), name
);
773 if (found_path
&& found_dest
) {
774 _cleanup_free_
char *t
= NULL
;
776 /* Filter out same name links in the main
778 t
= path_make_absolute(name
, config_path
);
782 b
= path_equal(t
, p
);
786 *same_name_link
= true;
787 else if (found_path
|| found_dest
)
795 static int find_symlinks(
796 const char *root_dir
,
798 const char *config_path
,
799 const LookupPaths
*lp
,
800 bool *same_name_link
) {
806 assert(same_name_link
);
808 fd
= open(config_path
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
);
810 if (IN_SET(errno
, ENOENT
, ENOTDIR
, EACCES
))
815 /* This takes possession of fd and closes it */
816 return find_symlinks_fd(root_dir
, name
, fd
, config_path
, config_path
, lp
, same_name_link
);
819 static int find_symlinks_in_scope(
821 const LookupPaths
*paths
,
823 UnitFileState
*state
) {
825 bool same_name_link_runtime
= false, same_name_link
= false;
829 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
833 /* First look in the persistent config path */
834 r
= find_symlinks(paths
->root_dir
, name
, paths
->persistent_config
, paths
, &same_name_link
);
838 *state
= UNIT_FILE_ENABLED
;
842 /* Then look in runtime config path */
843 r
= find_symlinks(paths
->root_dir
, name
, paths
->runtime_config
, paths
, &same_name_link_runtime
);
847 *state
= UNIT_FILE_ENABLED_RUNTIME
;
851 /* Hmm, we didn't find it, but maybe we found the same name
853 if (same_name_link
) {
854 *state
= UNIT_FILE_LINKED
;
857 if (same_name_link_runtime
) {
858 *state
= UNIT_FILE_LINKED_RUNTIME
;
865 static void install_info_free(UnitFileInstallInfo
*i
) {
872 strv_free(i
->aliases
);
873 strv_free(i
->wanted_by
);
874 strv_free(i
->required_by
);
876 free(i
->default_instance
);
877 free(i
->symlink_target
);
881 static OrderedHashmap
* install_info_hashmap_free(OrderedHashmap
*m
) {
882 UnitFileInstallInfo
*i
;
887 while ((i
= ordered_hashmap_steal_first(m
)))
888 install_info_free(i
);
890 return ordered_hashmap_free(m
);
893 static void install_context_done(InstallContext
*c
) {
896 c
->will_process
= install_info_hashmap_free(c
->will_process
);
897 c
->have_processed
= install_info_hashmap_free(c
->have_processed
);
900 static UnitFileInstallInfo
*install_info_find(InstallContext
*c
, const char *name
) {
901 UnitFileInstallInfo
*i
;
903 i
= ordered_hashmap_get(c
->have_processed
, name
);
907 return ordered_hashmap_get(c
->will_process
, name
);
910 static int install_info_may_process(
911 UnitFileInstallInfo
*i
,
912 const LookupPaths
*paths
,
913 UnitFileChange
**changes
,
914 unsigned *n_changes
) {
918 /* Checks whether the loaded unit file is one we should process, or is masked,
919 * transient or generated and thus not subject to enable/disable operations. */
921 if (i
->type
== UNIT_FILE_TYPE_MASKED
) {
922 unit_file_changes_add(changes
, n_changes
, -ERFKILL
, i
->path
, NULL
);
925 if (path_is_generator(paths
, i
->path
) ||
926 path_is_transient(paths
, i
->path
)) {
927 unit_file_changes_add(changes
, n_changes
, -EADDRNOTAVAIL
, i
->path
, NULL
);
928 return -EADDRNOTAVAIL
;
935 * Adds a new UnitFileInstallInfo entry under name in the InstallContext.will_process
936 * hashmap, or retrieves the existing one if already present.
938 static int install_info_add(
942 UnitFileInstallInfo
**ret
) {
944 UnitFileInstallInfo
*i
= NULL
;
948 assert(name
|| path
);
951 name
= basename(path
);
953 if (!unit_name_is_valid(name
, UNIT_NAME_ANY
))
956 i
= install_info_find(c
, name
);
963 r
= ordered_hashmap_ensure_allocated(&c
->will_process
, &string_hash_ops
);
967 i
= new0(UnitFileInstallInfo
, 1);
970 i
->type
= _UNIT_FILE_TYPE_INVALID
;
972 i
->name
= strdup(name
);
979 i
->path
= strdup(path
);
986 r
= ordered_hashmap_put(c
->will_process
, i
->name
, i
);
996 install_info_free(i
);
1000 static int config_parse_alias(
1002 const char *filename
,
1004 const char *section
,
1005 unsigned section_line
,
1019 name
= basename(filename
);
1020 type
= unit_name_to_type(name
);
1021 if (!unit_type_may_alias(type
))
1022 return log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1023 "Alias= is not allowed for %s units, ignoring.",
1024 unit_type_to_string(type
));
1026 return config_parse_strv(unit
, filename
, line
, section
, section_line
,
1027 lvalue
, ltype
, rvalue
, data
, userdata
);
1030 static int config_parse_also(
1032 const char *filename
,
1034 const char *section
,
1035 unsigned section_line
,
1042 UnitFileInstallInfo
*i
= userdata
;
1043 InstallContext
*c
= data
;
1051 _cleanup_free_
char *word
= NULL
;
1053 r
= extract_first_word(&rvalue
, &word
, NULL
, 0);
1059 r
= install_info_add(c
, word
, NULL
, NULL
);
1063 r
= strv_push(&i
->also
, word
);
1073 static int config_parse_default_instance(
1075 const char *filename
,
1077 const char *section
,
1078 unsigned section_line
,
1085 UnitFileInstallInfo
*i
= data
;
1087 _cleanup_free_
char *printed
= NULL
;
1094 name
= basename(filename
);
1095 if (unit_name_is_valid(name
, UNIT_NAME_INSTANCE
))
1096 /* When enabling an instance, we might be using a template unit file,
1097 * but we should ignore DefaultInstance silently. */
1099 if (!unit_name_is_valid(name
, UNIT_NAME_TEMPLATE
))
1100 return log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1101 "DefaultInstance= only makes sense for template units, ignoring.");
1103 r
= install_full_printf(i
, rvalue
, &printed
);
1107 if (!unit_instance_is_valid(printed
))
1110 return free_and_replace(i
->default_instance
, printed
);
1113 static int unit_file_load(
1115 UnitFileInstallInfo
*info
,
1117 SearchFlags flags
) {
1119 const ConfigTableItem items
[] = {
1120 { "Install", "Alias", config_parse_alias
, 0, &info
->aliases
},
1121 { "Install", "WantedBy", config_parse_strv
, 0, &info
->wanted_by
},
1122 { "Install", "RequiredBy", config_parse_strv
, 0, &info
->required_by
},
1123 { "Install", "DefaultInstance", config_parse_default_instance
, 0, info
},
1124 { "Install", "Also", config_parse_also
, 0, c
},
1130 _cleanup_fclose_
FILE *f
= NULL
;
1131 _cleanup_close_
int fd
= -1;
1138 name
= basename(path
);
1139 type
= unit_name_to_type(name
);
1140 if (unit_name_is_valid(name
, UNIT_NAME_TEMPLATE
|UNIT_NAME_INSTANCE
) &&
1141 !unit_type_may_template(type
))
1142 return log_error_errno(EINVAL
, "Unit type %s cannot be templated.", unit_type_to_string(type
));
1144 if (!(flags
& SEARCH_LOAD
)) {
1145 r
= lstat(path
, &st
);
1149 if (null_or_empty(&st
))
1150 info
->type
= UNIT_FILE_TYPE_MASKED
;
1151 else if (S_ISREG(st
.st_mode
))
1152 info
->type
= UNIT_FILE_TYPE_REGULAR
;
1153 else if (S_ISLNK(st
.st_mode
))
1155 else if (S_ISDIR(st
.st_mode
))
1163 /* c is only needed if we actually load the file */
1166 fd
= open(path
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
|O_NOFOLLOW
);
1169 if (fstat(fd
, &st
) < 0)
1171 if (null_or_empty(&st
)) {
1172 info
->type
= UNIT_FILE_TYPE_MASKED
;
1175 if (S_ISDIR(st
.st_mode
))
1177 if (!S_ISREG(st
.st_mode
))
1180 f
= fdopen(fd
, "re");
1185 r
= config_parse(NULL
, path
, f
,
1187 config_item_table_lookup
, items
,
1188 true, true, false, info
);
1192 info
->type
= UNIT_FILE_TYPE_REGULAR
;
1195 (int) strv_length(info
->aliases
) +
1196 (int) strv_length(info
->wanted_by
) +
1197 (int) strv_length(info
->required_by
);
1200 static int unit_file_load_or_readlink(
1202 UnitFileInstallInfo
*info
,
1204 const char *root_dir
,
1205 SearchFlags flags
) {
1207 _cleanup_free_
char *target
= NULL
;
1210 r
= unit_file_load(c
, info
, path
, flags
);
1214 /* This is a symlink, let's read it. */
1216 r
= readlink_malloc(path
, &target
);
1220 if (path_equal(target
, "/dev/null"))
1221 info
->type
= UNIT_FILE_TYPE_MASKED
;
1226 bn
= basename(target
);
1228 if (unit_name_is_valid(info
->name
, UNIT_NAME_PLAIN
)) {
1230 if (!unit_name_is_valid(bn
, UNIT_NAME_PLAIN
))
1233 } else if (unit_name_is_valid(info
->name
, UNIT_NAME_INSTANCE
)) {
1235 if (!unit_name_is_valid(bn
, UNIT_NAME_INSTANCE
|UNIT_NAME_TEMPLATE
))
1238 } else if (unit_name_is_valid(info
->name
, UNIT_NAME_TEMPLATE
)) {
1240 if (!unit_name_is_valid(bn
, UNIT_NAME_TEMPLATE
))
1245 /* Enforce that the symlink destination does not
1246 * change the unit file type. */
1248 a
= unit_name_to_type(info
->name
);
1249 b
= unit_name_to_type(bn
);
1250 if (a
< 0 || b
< 0 || a
!= b
)
1253 if (path_is_absolute(target
))
1254 /* This is an absolute path, prefix the root so that we always deal with fully qualified paths */
1255 info
->symlink_target
= prefix_root(root_dir
, target
);
1257 /* This is a relative path, take it relative to the dir the symlink is located in. */
1258 info
->symlink_target
= file_in_same_dir(path
, target
);
1259 if (!info
->symlink_target
)
1262 info
->type
= UNIT_FILE_TYPE_SYMLINK
;
1268 static int unit_file_search(
1270 UnitFileInstallInfo
*info
,
1271 const LookupPaths
*paths
,
1272 SearchFlags flags
) {
1274 _cleanup_free_
char *template = NULL
;
1281 /* Was this unit already loaded? */
1282 if (info
->type
!= _UNIT_FILE_TYPE_INVALID
)
1286 return unit_file_load_or_readlink(c
, info
, info
->path
, paths
->root_dir
, flags
);
1290 STRV_FOREACH(p
, paths
->search_path
) {
1291 _cleanup_free_
char *path
= NULL
;
1293 path
= strjoin(*p
, "/", info
->name
, NULL
);
1297 r
= unit_file_load_or_readlink(c
, info
, path
, paths
->root_dir
, flags
);
1302 } else if (!IN_SET(r
, -ENOENT
, -ENOTDIR
, -EACCES
))
1306 if (unit_name_is_valid(info
->name
, UNIT_NAME_INSTANCE
)) {
1307 /* Unit file doesn't exist, however instance
1308 * enablement was requested. We will check if it is
1309 * possible to load template unit file. */
1311 r
= unit_name_template(info
->name
, &template);
1315 STRV_FOREACH(p
, paths
->search_path
) {
1316 _cleanup_free_
char *path
= NULL
;
1318 path
= strjoin(*p
, "/", template, NULL
);
1322 r
= unit_file_load_or_readlink(c
, info
, path
, paths
->root_dir
, flags
);
1327 } else if (!IN_SET(r
, -ENOENT
, -ENOTDIR
, -EACCES
))
1332 log_debug("Cannot find unit %s%s%s.", info
->name
, template ? " or " : "", strempty(template));
1336 static int install_info_follow(
1338 UnitFileInstallInfo
*i
,
1339 const char *root_dir
,
1340 SearchFlags flags
) {
1345 if (i
->type
!= UNIT_FILE_TYPE_SYMLINK
)
1347 if (!i
->symlink_target
)
1350 /* If the basename doesn't match, the caller should add a
1351 * complete new entry for this. */
1353 if (!streq(basename(i
->symlink_target
), i
->name
))
1356 free_and_replace(i
->path
, i
->symlink_target
);
1357 i
->type
= _UNIT_FILE_TYPE_INVALID
;
1359 return unit_file_load_or_readlink(c
, i
, i
->path
, root_dir
, flags
);
1363 * Search for the unit file. If the unit name is a symlink, follow the symlink to the
1364 * target, maybe more than once. Propagate the instance name if present.
1366 static int install_info_traverse(
1367 UnitFileScope scope
,
1369 const LookupPaths
*paths
,
1370 UnitFileInstallInfo
*start
,
1372 UnitFileInstallInfo
**ret
) {
1374 UnitFileInstallInfo
*i
;
1382 r
= unit_file_search(c
, start
, paths
, flags
);
1387 while (i
->type
== UNIT_FILE_TYPE_SYMLINK
) {
1388 /* Follow the symlink */
1390 if (++k
> UNIT_FILE_FOLLOW_SYMLINK_MAX
)
1393 if (!(flags
& SEARCH_FOLLOW_CONFIG_SYMLINKS
)) {
1394 r
= path_is_config(paths
, i
->path
);
1401 r
= install_info_follow(c
, i
, paths
->root_dir
, flags
);
1403 _cleanup_free_
char *buffer
= NULL
;
1406 /* Target has a different name, create a new
1407 * install info object for that, and continue
1410 bn
= basename(i
->symlink_target
);
1412 if (unit_name_is_valid(i
->name
, UNIT_NAME_INSTANCE
) &&
1413 unit_name_is_valid(bn
, UNIT_NAME_TEMPLATE
)) {
1415 _cleanup_free_
char *instance
= NULL
;
1417 r
= unit_name_to_instance(i
->name
, &instance
);
1421 r
= unit_name_replace_instance(bn
, instance
, &buffer
);
1428 r
= install_info_add(c
, bn
, NULL
, &i
);
1432 /* Try again, with the new target we found. */
1433 r
= unit_file_search(c
, i
, paths
, flags
);
1435 /* Translate error code to highlight this specific case */
1450 * Call install_info_add() with name_or_path as the path (if name_or_path starts with "/")
1451 * or the name (otherwise). root_dir is prepended to the path.
1453 static int install_info_add_auto(
1455 const LookupPaths
*paths
,
1456 const char *name_or_path
,
1457 UnitFileInstallInfo
**ret
) {
1460 assert(name_or_path
);
1462 if (path_is_absolute(name_or_path
)) {
1465 pp
= prefix_roota(paths
->root_dir
, name_or_path
);
1467 return install_info_add(c
, NULL
, pp
, ret
);
1469 return install_info_add(c
, name_or_path
, NULL
, ret
);
1472 static int install_info_discover(
1473 UnitFileScope scope
,
1475 const LookupPaths
*paths
,
1478 UnitFileInstallInfo
**ret
) {
1480 UnitFileInstallInfo
*i
;
1487 r
= install_info_add_auto(c
, paths
, name
, &i
);
1491 return install_info_traverse(scope
, c
, paths
, i
, flags
, ret
);
1494 static int install_info_symlink_alias(
1495 UnitFileInstallInfo
*i
,
1496 const LookupPaths
*paths
,
1497 const char *config_path
,
1499 UnitFileChange
**changes
,
1500 unsigned *n_changes
) {
1507 assert(config_path
);
1509 STRV_FOREACH(s
, i
->aliases
) {
1510 _cleanup_free_
char *alias_path
= NULL
, *dst
= NULL
;
1512 q
= install_full_printf(i
, *s
, &dst
);
1516 alias_path
= path_make_absolute(dst
, config_path
);
1520 q
= create_symlink(paths
, i
->path
, alias_path
, force
, changes
, n_changes
);
1528 static int install_info_symlink_wants(
1529 UnitFileInstallInfo
*i
,
1530 const LookupPaths
*paths
,
1531 const char *config_path
,
1534 UnitFileChange
**changes
,
1535 unsigned *n_changes
) {
1537 _cleanup_free_
char *buf
= NULL
;
1544 assert(config_path
);
1546 if (strv_isempty(list
))
1549 if (unit_name_is_valid(i
->name
, UNIT_NAME_TEMPLATE
)) {
1550 UnitFileInstallInfo instance
= {
1551 .type
= _UNIT_FILE_TYPE_INVALID
,
1553 _cleanup_free_
char *path
= NULL
;
1555 /* Don't install any symlink if there's no default
1556 * instance configured */
1558 if (!i
->default_instance
)
1561 r
= unit_name_replace_instance(i
->name
, i
->default_instance
, &buf
);
1565 instance
.name
= buf
;
1566 r
= unit_file_search(NULL
, &instance
, paths
, SEARCH_FOLLOW_CONFIG_SYMLINKS
);
1570 path
= instance
.path
;
1571 instance
.path
= NULL
;
1573 if (instance
.type
== UNIT_FILE_TYPE_MASKED
) {
1574 unit_file_changes_add(changes
, n_changes
, -ERFKILL
, path
, NULL
);
1582 STRV_FOREACH(s
, list
) {
1583 _cleanup_free_
char *path
= NULL
, *dst
= NULL
;
1585 q
= install_full_printf(i
, *s
, &dst
);
1589 if (!unit_name_is_valid(dst
, UNIT_NAME_ANY
)) {
1594 path
= strjoin(config_path
, "/", dst
, suffix
, n
, NULL
);
1598 q
= create_symlink(paths
, i
->path
, path
, true, changes
, n_changes
);
1606 static int install_info_symlink_link(
1607 UnitFileInstallInfo
*i
,
1608 const LookupPaths
*paths
,
1609 const char *config_path
,
1611 UnitFileChange
**changes
,
1612 unsigned *n_changes
) {
1614 _cleanup_free_
char *path
= NULL
;
1619 assert(config_path
);
1622 r
= in_search_path(paths
, i
->path
);
1628 path
= strjoin(config_path
, "/", i
->name
, NULL
);
1632 return create_symlink(paths
, i
->path
, path
, force
, changes
, n_changes
);
1635 static int install_info_apply(
1636 UnitFileInstallInfo
*i
,
1637 const LookupPaths
*paths
,
1638 const char *config_path
,
1640 UnitFileChange
**changes
,
1641 unsigned *n_changes
) {
1647 assert(config_path
);
1649 if (i
->type
!= UNIT_FILE_TYPE_REGULAR
)
1652 r
= install_info_symlink_alias(i
, paths
, config_path
, force
, changes
, n_changes
);
1654 q
= install_info_symlink_wants(i
, paths
, config_path
, i
->wanted_by
, ".wants/", changes
, n_changes
);
1658 q
= install_info_symlink_wants(i
, paths
, config_path
, i
->required_by
, ".requires/", changes
, n_changes
);
1662 q
= install_info_symlink_link(i
, paths
, config_path
, force
, changes
, n_changes
);
1663 /* Do not count links to the unit file towards the "carries_install_info" count */
1664 if (r
== 0 && q
< 0)
1670 static int install_context_apply(
1671 UnitFileScope scope
,
1673 const LookupPaths
*paths
,
1674 const char *config_path
,
1677 UnitFileChange
**changes
,
1678 unsigned *n_changes
) {
1680 UnitFileInstallInfo
*i
;
1685 assert(config_path
);
1687 if (ordered_hashmap_isempty(c
->will_process
))
1690 r
= ordered_hashmap_ensure_allocated(&c
->have_processed
, &string_hash_ops
);
1695 while ((i
= ordered_hashmap_first(c
->will_process
))) {
1698 q
= ordered_hashmap_move_one(c
->have_processed
, c
->will_process
, i
->name
);
1702 r
= install_info_traverse(scope
, c
, paths
, i
, flags
, NULL
);
1706 /* We can attempt to process a masked unit when a different unit
1707 * that we were processing specifies it in Also=. */
1708 if (i
->type
== UNIT_FILE_TYPE_MASKED
) {
1709 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_IS_MASKED
, i
->path
, NULL
);
1711 /* Assume that something *could* have been enabled here,
1712 * avoid "empty [Install] section" warning. */
1717 if (i
->type
!= UNIT_FILE_TYPE_REGULAR
)
1720 q
= install_info_apply(i
, paths
, config_path
, force
, changes
, n_changes
);
1732 static int install_context_mark_for_removal(
1733 UnitFileScope scope
,
1735 const LookupPaths
*paths
,
1736 Set
**remove_symlinks_to
,
1737 const char *config_path
) {
1739 UnitFileInstallInfo
*i
;
1744 assert(config_path
);
1746 /* Marks all items for removal */
1748 if (ordered_hashmap_isempty(c
->will_process
))
1751 r
= ordered_hashmap_ensure_allocated(&c
->have_processed
, &string_hash_ops
);
1755 while ((i
= ordered_hashmap_first(c
->will_process
))) {
1757 r
= ordered_hashmap_move_one(c
->have_processed
, c
->will_process
, i
->name
);
1761 r
= install_info_traverse(scope
, c
, paths
, i
, SEARCH_LOAD
|SEARCH_FOLLOW_CONFIG_SYMLINKS
, NULL
);
1767 if (i
->type
!= UNIT_FILE_TYPE_REGULAR
) {
1768 log_debug("Unit %s has type %s, ignoring.",
1770 unit_file_type_to_string(i
->type
) ?: "invalid");
1774 r
= mark_symlink_for_removal(remove_symlinks_to
, i
->name
);
1783 UnitFileScope scope
,
1785 const char *root_dir
,
1788 UnitFileChange
**changes
,
1789 unsigned *n_changes
) {
1791 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
1792 const char *config_path
;
1797 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
1799 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
1803 config_path
= runtime
? paths
.runtime_config
: paths
.persistent_config
;
1805 STRV_FOREACH(i
, files
) {
1806 _cleanup_free_
char *path
= NULL
;
1809 if (!unit_name_is_valid(*i
, UNIT_NAME_ANY
)) {
1815 path
= path_make_absolute(*i
, config_path
);
1819 q
= create_symlink(&paths
, "/dev/null", path
, force
, changes
, n_changes
);
1820 if (q
< 0 && r
>= 0)
1827 int unit_file_unmask(
1828 UnitFileScope scope
,
1830 const char *root_dir
,
1832 UnitFileChange
**changes
,
1833 unsigned *n_changes
) {
1835 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
1836 _cleanup_set_free_free_ Set
*remove_symlinks_to
= NULL
;
1837 _cleanup_free_
char **todo
= NULL
;
1838 size_t n_todo
= 0, n_allocated
= 0;
1839 const char *config_path
;
1844 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
1846 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
1850 config_path
= runtime
? paths
.runtime_config
: paths
.persistent_config
;
1852 STRV_FOREACH(i
, files
) {
1853 _cleanup_free_
char *path
= NULL
;
1855 if (!unit_name_is_valid(*i
, UNIT_NAME_ANY
))
1858 path
= path_make_absolute(*i
, config_path
);
1862 r
= null_or_empty_path(path
);
1870 if (!GREEDY_REALLOC0(todo
, n_allocated
, n_todo
+ 2))
1873 todo
[n_todo
++] = *i
;
1879 STRV_FOREACH(i
, todo
) {
1880 _cleanup_free_
char *path
= NULL
;
1883 path
= path_make_absolute(*i
, config_path
);
1887 if (unlink(path
) < 0) {
1888 if (errno
!= ENOENT
) {
1891 unit_file_changes_add(changes
, n_changes
, -errno
, path
, NULL
);
1897 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_UNLINK
, path
, NULL
);
1899 rp
= skip_root(&paths
, path
);
1900 q
= mark_symlink_for_removal(&remove_symlinks_to
, rp
?: path
);
1905 q
= remove_marked_symlinks(remove_symlinks_to
, config_path
, &paths
, changes
, n_changes
);
1913 UnitFileScope scope
,
1915 const char *root_dir
,
1918 UnitFileChange
**changes
,
1919 unsigned *n_changes
) {
1921 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
1922 _cleanup_free_
char **todo
= NULL
;
1923 size_t n_todo
= 0, n_allocated
= 0;
1924 const char *config_path
;
1929 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
1931 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
1935 config_path
= runtime
? paths
.runtime_config
: paths
.persistent_config
;
1937 STRV_FOREACH(i
, files
) {
1938 _cleanup_free_
char *full
= NULL
;
1942 if (!path_is_absolute(*i
))
1946 if (!unit_name_is_valid(fn
, UNIT_NAME_ANY
))
1949 full
= prefix_root(paths
.root_dir
, *i
);
1953 if (lstat(full
, &st
) < 0)
1955 if (S_ISLNK(st
.st_mode
))
1957 if (S_ISDIR(st
.st_mode
))
1959 if (!S_ISREG(st
.st_mode
))
1962 q
= in_search_path(&paths
, *i
);
1968 if (!GREEDY_REALLOC0(todo
, n_allocated
, n_todo
+ 2))
1971 todo
[n_todo
++] = *i
;
1977 STRV_FOREACH(i
, todo
) {
1978 _cleanup_free_
char *new_path
= NULL
;
1980 new_path
= path_make_absolute(basename(*i
), config_path
);
1984 q
= create_symlink(&paths
, *i
, new_path
, force
, changes
, n_changes
);
1985 if (q
< 0 && r
>= 0)
1992 static int path_shall_revert(const LookupPaths
*paths
, const char *path
) {
1998 /* Checks whether the path is one where the drop-in directories shall be removed. */
2000 r
= path_is_config(paths
, path
);
2004 r
= path_is_control(paths
, path
);
2008 return path_is_transient(paths
, path
);
2011 int unit_file_revert(
2012 UnitFileScope scope
,
2013 const char *root_dir
,
2015 UnitFileChange
**changes
,
2016 unsigned *n_changes
) {
2018 _cleanup_set_free_free_ Set
*remove_symlinks_to
= NULL
;
2019 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2020 _cleanup_strv_free_
char **todo
= NULL
;
2021 size_t n_todo
= 0, n_allocated
= 0;
2025 /* Puts a unit file back into vendor state. This means:
2027 * a) we remove all drop-in snippets added by the user ("config"), add to transient units ("transient"), and
2028 * added via "systemctl set-property" ("control"), but not if the drop-in is generated ("generated").
2030 * c) if there's a vendor unit file (i.e. one in /usr) we remove any configured overriding unit files (i.e. in
2031 * "config", but not in "transient" or "control" or even "generated").
2033 * We remove all that in both the runtime and the persistent directories, if that applies.
2036 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2040 STRV_FOREACH(i
, files
) {
2041 bool has_vendor
= false;
2044 if (!unit_name_is_valid(*i
, UNIT_NAME_ANY
))
2047 STRV_FOREACH(p
, paths
.search_path
) {
2048 _cleanup_free_
char *path
= NULL
, *dropin
= NULL
;
2051 path
= path_make_absolute(*i
, *p
);
2055 r
= lstat(path
, &st
);
2057 if (errno
!= ENOENT
)
2059 } else if (S_ISREG(st
.st_mode
)) {
2060 /* Check if there's a vendor version */
2061 r
= path_is_vendor(&paths
, path
);
2068 dropin
= strappend(path
, ".d");
2072 r
= lstat(dropin
, &st
);
2074 if (errno
!= ENOENT
)
2076 } else if (S_ISDIR(st
.st_mode
)) {
2077 /* Remove the drop-ins */
2078 r
= path_shall_revert(&paths
, dropin
);
2082 if (!GREEDY_REALLOC0(todo
, n_allocated
, n_todo
+ 2))
2085 todo
[n_todo
++] = dropin
;
2094 /* OK, there's a vendor version, hence drop all configuration versions */
2095 STRV_FOREACH(p
, paths
.search_path
) {
2096 _cleanup_free_
char *path
= NULL
;
2099 path
= path_make_absolute(*i
, *p
);
2103 r
= lstat(path
, &st
);
2105 if (errno
!= ENOENT
)
2107 } else if (S_ISREG(st
.st_mode
) || S_ISLNK(st
.st_mode
)) {
2108 r
= path_is_config(&paths
, path
);
2112 if (!GREEDY_REALLOC0(todo
, n_allocated
, n_todo
+ 2))
2115 todo
[n_todo
++] = path
;
2125 STRV_FOREACH(i
, todo
) {
2126 _cleanup_strv_free_
char **fs
= NULL
;
2130 (void) get_files_in_directory(*i
, &fs
);
2132 q
= rm_rf(*i
, REMOVE_ROOT
|REMOVE_PHYSICAL
);
2133 if (q
< 0 && q
!= -ENOENT
&& r
>= 0) {
2138 STRV_FOREACH(j
, fs
) {
2139 _cleanup_free_
char *t
= NULL
;
2141 t
= strjoin(*i
, "/", *j
, NULL
);
2145 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_UNLINK
, t
, NULL
);
2148 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_UNLINK
, *i
, NULL
);
2150 rp
= skip_root(&paths
, *i
);
2151 q
= mark_symlink_for_removal(&remove_symlinks_to
, rp
?: *i
);
2156 q
= remove_marked_symlinks(remove_symlinks_to
, paths
.runtime_config
, &paths
, changes
, n_changes
);
2160 q
= remove_marked_symlinks(remove_symlinks_to
, paths
.persistent_config
, &paths
, changes
, n_changes
);
2167 int unit_file_add_dependency(
2168 UnitFileScope scope
,
2170 const char *root_dir
,
2175 UnitFileChange
**changes
,
2176 unsigned *n_changes
) {
2178 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2179 _cleanup_(install_context_done
) InstallContext c
= {};
2180 UnitFileInstallInfo
*i
, *target_info
;
2181 const char *config_path
;
2186 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2189 if (!IN_SET(dep
, UNIT_WANTS
, UNIT_REQUIRES
))
2192 if (!unit_name_is_valid(target
, UNIT_NAME_ANY
))
2195 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2199 config_path
= runtime
? paths
.runtime_config
: paths
.persistent_config
;
2201 r
= install_info_discover(scope
, &c
, &paths
, target
, SEARCH_FOLLOW_CONFIG_SYMLINKS
, &target_info
);
2204 r
= install_info_may_process(target_info
, &paths
, changes
, n_changes
);
2208 assert(target_info
->type
== UNIT_FILE_TYPE_REGULAR
);
2210 STRV_FOREACH(f
, files
) {
2213 r
= install_info_discover(scope
, &c
, &paths
, *f
, SEARCH_FOLLOW_CONFIG_SYMLINKS
, &i
);
2216 r
= install_info_may_process(i
, &paths
, changes
, n_changes
);
2220 assert(i
->type
== UNIT_FILE_TYPE_REGULAR
);
2222 /* We didn't actually load anything from the unit
2223 * file, but instead just add in our new symlink to
2226 if (dep
== UNIT_WANTS
)
2229 l
= &i
->required_by
;
2232 *l
= strv_new(target_info
->name
, NULL
);
2237 return install_context_apply(scope
, &c
, &paths
, config_path
, force
, SEARCH_FOLLOW_CONFIG_SYMLINKS
, changes
, n_changes
);
2240 int unit_file_enable(
2241 UnitFileScope scope
,
2243 const char *root_dir
,
2246 UnitFileChange
**changes
,
2247 unsigned *n_changes
) {
2249 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2250 _cleanup_(install_context_done
) InstallContext c
= {};
2251 const char *config_path
;
2252 UnitFileInstallInfo
*i
;
2257 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2259 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2263 config_path
= runtime
? paths
.runtime_config
: paths
.persistent_config
;
2265 STRV_FOREACH(f
, files
) {
2266 r
= install_info_discover(scope
, &c
, &paths
, *f
, SEARCH_LOAD
|SEARCH_FOLLOW_CONFIG_SYMLINKS
, &i
);
2269 r
= install_info_may_process(i
, &paths
, changes
, n_changes
);
2273 assert(i
->type
== UNIT_FILE_TYPE_REGULAR
);
2276 /* This will return the number of symlink rules that were
2277 supposed to be created, not the ones actually created. This
2278 is useful to determine whether the passed files had any
2279 installation data at all. */
2281 return install_context_apply(scope
, &c
, &paths
, config_path
, force
, SEARCH_LOAD
, changes
, n_changes
);
2284 int unit_file_disable(
2285 UnitFileScope scope
,
2287 const char *root_dir
,
2289 UnitFileChange
**changes
,
2290 unsigned *n_changes
) {
2292 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2293 _cleanup_(install_context_done
) InstallContext c
= {};
2294 _cleanup_set_free_free_ Set
*remove_symlinks_to
= NULL
;
2295 const char *config_path
;
2300 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2302 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2306 config_path
= runtime
? paths
.runtime_config
: paths
.persistent_config
;
2308 STRV_FOREACH(i
, files
) {
2309 if (!unit_name_is_valid(*i
, UNIT_NAME_ANY
))
2312 r
= install_info_add(&c
, *i
, NULL
, NULL
);
2317 r
= install_context_mark_for_removal(scope
, &c
, &paths
, &remove_symlinks_to
, config_path
);
2321 return remove_marked_symlinks(remove_symlinks_to
, config_path
, &paths
, changes
, n_changes
);
2324 int unit_file_reenable(
2325 UnitFileScope scope
,
2327 const char *root_dir
,
2330 UnitFileChange
**changes
,
2331 unsigned *n_changes
) {
2337 /* First, we invoke the disable command with only the basename... */
2338 l
= strv_length(files
);
2339 n
= newa(char*, l
+1);
2340 for (i
= 0; i
< l
; i
++)
2341 n
[i
] = basename(files
[i
]);
2344 r
= unit_file_disable(scope
, runtime
, root_dir
, n
, changes
, n_changes
);
2348 /* But the enable command with the full name */
2349 return unit_file_enable(scope
, runtime
, root_dir
, files
, force
, changes
, n_changes
);
2352 int unit_file_set_default(
2353 UnitFileScope scope
,
2354 const char *root_dir
,
2357 UnitFileChange
**changes
,
2358 unsigned *n_changes
) {
2360 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2361 _cleanup_(install_context_done
) InstallContext c
= {};
2362 UnitFileInstallInfo
*i
;
2363 const char *new_path
;
2367 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2370 if (unit_name_to_type(name
) != UNIT_TARGET
) /* this also validates the name */
2372 if (streq(name
, SPECIAL_DEFAULT_TARGET
))
2375 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2379 r
= install_info_discover(scope
, &c
, &paths
, name
, 0, &i
);
2382 r
= install_info_may_process(i
, &paths
, changes
, n_changes
);
2386 new_path
= strjoina(paths
.persistent_config
, "/" SPECIAL_DEFAULT_TARGET
);
2387 return create_symlink(&paths
, i
->path
, new_path
, force
, changes
, n_changes
);
2390 int unit_file_get_default(
2391 UnitFileScope scope
,
2392 const char *root_dir
,
2395 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2396 _cleanup_(install_context_done
) InstallContext c
= {};
2397 UnitFileInstallInfo
*i
;
2402 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2405 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2409 r
= install_info_discover(scope
, &c
, &paths
, SPECIAL_DEFAULT_TARGET
, SEARCH_FOLLOW_CONFIG_SYMLINKS
, &i
);
2412 r
= install_info_may_process(i
, &paths
, NULL
, 0);
2416 n
= strdup(i
->name
);
2424 static int unit_file_lookup_state(
2425 UnitFileScope scope
,
2426 const LookupPaths
*paths
,
2428 UnitFileState
*ret
) {
2430 _cleanup_(install_context_done
) InstallContext c
= {};
2431 UnitFileInstallInfo
*i
;
2432 UnitFileState state
;
2438 if (!unit_name_is_valid(name
, UNIT_NAME_ANY
))
2441 r
= install_info_discover(scope
, &c
, paths
, name
, SEARCH_LOAD
|SEARCH_FOLLOW_CONFIG_SYMLINKS
, &i
);
2445 /* Shortcut things, if the caller just wants to know if this unit exists. */
2451 case UNIT_FILE_TYPE_MASKED
:
2452 r
= path_is_runtime(paths
, i
->path
);
2456 state
= r
> 0 ? UNIT_FILE_MASKED_RUNTIME
: UNIT_FILE_MASKED
;
2459 case UNIT_FILE_TYPE_REGULAR
:
2460 r
= path_is_generator(paths
, i
->path
);
2464 state
= UNIT_FILE_GENERATED
;
2468 r
= path_is_transient(paths
, i
->path
);
2472 state
= UNIT_FILE_TRANSIENT
;
2476 r
= find_symlinks_in_scope(scope
, paths
, i
->name
, &state
);
2480 if (UNIT_FILE_INSTALL_INFO_HAS_RULES(i
))
2481 state
= UNIT_FILE_DISABLED
;
2482 else if (UNIT_FILE_INSTALL_INFO_HAS_ALSO(i
))
2483 state
= UNIT_FILE_INDIRECT
;
2485 state
= UNIT_FILE_STATIC
;
2491 assert_not_reached("Unexpect unit file type.");
2498 int unit_file_get_state(
2499 UnitFileScope scope
,
2500 const char *root_dir
,
2502 UnitFileState
*ret
) {
2504 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2508 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2511 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2515 return unit_file_lookup_state(scope
, &paths
, name
, ret
);
2518 int unit_file_exists(UnitFileScope scope
, const LookupPaths
*paths
, const char *name
) {
2519 _cleanup_(install_context_done
) InstallContext c
= {};
2525 if (!unit_name_is_valid(name
, UNIT_NAME_ANY
))
2528 r
= install_info_discover(scope
, &c
, paths
, name
, 0, NULL
);
2537 static int read_presets(UnitFileScope scope
, const char *root_dir
, Presets
*presets
) {
2538 _cleanup_(presets_freep
) Presets ps
= {};
2539 size_t n_allocated
= 0;
2540 _cleanup_strv_free_
char **files
= NULL
;
2545 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2548 if (scope
== UNIT_FILE_SYSTEM
)
2549 r
= conf_files_list(&files
, ".preset", root_dir
,
2550 "/etc/systemd/system-preset",
2551 "/usr/local/lib/systemd/system-preset",
2552 "/usr/lib/systemd/system-preset",
2553 #ifdef HAVE_SPLIT_USR
2554 "/lib/systemd/system-preset",
2557 else if (scope
== UNIT_FILE_GLOBAL
)
2558 r
= conf_files_list(&files
, ".preset", root_dir
,
2559 "/etc/systemd/user-preset",
2560 "/usr/local/lib/systemd/user-preset",
2561 "/usr/lib/systemd/user-preset",
2564 *presets
= (Presets
){};
2572 STRV_FOREACH(p
, files
) {
2573 _cleanup_fclose_
FILE *f
;
2574 char line
[LINE_MAX
];
2577 f
= fopen(*p
, "re");
2579 if (errno
== ENOENT
)
2585 FOREACH_LINE(line
, f
, return -errno
) {
2586 PresetRule rule
= {};
2587 const char *parameter
;
2595 if (strchr(COMMENTS
, *l
))
2598 parameter
= first_word(l
, "enable");
2602 pattern
= strdup(parameter
);
2606 rule
= (PresetRule
) {
2608 .action
= PRESET_ENABLE
,
2612 parameter
= first_word(l
, "disable");
2616 pattern
= strdup(parameter
);
2620 rule
= (PresetRule
) {
2622 .action
= PRESET_DISABLE
,
2627 if (!GREEDY_REALLOC(ps
.rules
, n_allocated
, ps
.n_rules
+ 1))
2630 ps
.rules
[ps
.n_rules
++] = rule
;
2634 log_syntax(NULL
, LOG_WARNING
, *p
, n
, 0, "Couldn't parse line '%s'. Ignoring.", line
);
2644 static int query_presets(const char *name
, const Presets presets
) {
2645 PresetAction action
= PRESET_UNKNOWN
;
2648 if (!unit_name_is_valid(name
, UNIT_NAME_ANY
))
2651 for (i
= 0; i
< presets
.n_rules
; i
++)
2652 if (fnmatch(presets
.rules
[i
].pattern
, name
, FNM_NOESCAPE
) == 0) {
2653 action
= presets
.rules
[i
].action
;
2658 case PRESET_UNKNOWN
:
2659 log_debug("Preset files don't specify rule for %s. Enabling.", name
);
2662 log_debug("Preset files say enable %s.", name
);
2664 case PRESET_DISABLE
:
2665 log_debug("Preset files say disable %s.", name
);
2668 assert_not_reached("invalid preset action");
2672 int unit_file_query_preset(UnitFileScope scope
, const char *root_dir
, const char *name
) {
2673 _cleanup_(presets_freep
) Presets presets
= {};
2676 r
= read_presets(scope
, root_dir
, &presets
);
2680 return query_presets(name
, presets
);
2683 static int execute_preset(
2684 UnitFileScope scope
,
2685 InstallContext
*plus
,
2686 InstallContext
*minus
,
2687 const LookupPaths
*paths
,
2688 const char *config_path
,
2690 UnitFilePresetMode mode
,
2692 UnitFileChange
**changes
,
2693 unsigned *n_changes
) {
2700 assert(config_path
);
2702 if (mode
!= UNIT_FILE_PRESET_ENABLE_ONLY
) {
2703 _cleanup_set_free_free_ Set
*remove_symlinks_to
= NULL
;
2705 r
= install_context_mark_for_removal(scope
, minus
, paths
, &remove_symlinks_to
, config_path
);
2709 r
= remove_marked_symlinks(remove_symlinks_to
, config_path
, paths
, changes
, n_changes
);
2713 if (mode
!= UNIT_FILE_PRESET_DISABLE_ONLY
) {
2716 /* Returns number of symlinks that where supposed to be installed. */
2717 q
= install_context_apply(scope
, plus
, paths
, config_path
, force
, SEARCH_LOAD
, changes
, n_changes
);
2729 static int preset_prepare_one(
2730 UnitFileScope scope
,
2731 InstallContext
*plus
,
2732 InstallContext
*minus
,
2736 UnitFileChange
**changes
,
2737 unsigned *n_changes
) {
2739 _cleanup_(install_context_done
) InstallContext tmp
= {};
2740 UnitFileInstallInfo
*i
;
2743 if (install_info_find(plus
, name
) || install_info_find(minus
, name
))
2746 r
= install_info_discover(scope
, &tmp
, paths
, name
, SEARCH_FOLLOW_CONFIG_SYMLINKS
, &i
);
2749 if (!streq(name
, i
->name
)) {
2750 log_debug("Skipping %s because is an alias for %s", name
, i
->name
);
2754 r
= query_presets(name
, presets
);
2759 r
= install_info_discover(scope
, plus
, paths
, name
, SEARCH_LOAD
|SEARCH_FOLLOW_CONFIG_SYMLINKS
, &i
);
2763 r
= install_info_may_process(i
, paths
, changes
, n_changes
);
2767 r
= install_info_discover(scope
, minus
, paths
, name
, SEARCH_FOLLOW_CONFIG_SYMLINKS
, &i
);
2772 int unit_file_preset(
2773 UnitFileScope scope
,
2775 const char *root_dir
,
2777 UnitFilePresetMode mode
,
2779 UnitFileChange
**changes
,
2780 unsigned *n_changes
) {
2782 _cleanup_(install_context_done
) InstallContext plus
= {}, minus
= {};
2783 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2784 _cleanup_(presets_freep
) Presets presets
= {};
2785 const char *config_path
;
2790 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2791 assert(mode
< _UNIT_FILE_PRESET_MAX
);
2793 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2797 config_path
= runtime
? paths
.runtime_config
: paths
.persistent_config
;
2799 r
= read_presets(scope
, root_dir
, &presets
);
2803 STRV_FOREACH(i
, files
) {
2804 r
= preset_prepare_one(scope
, &plus
, &minus
, &paths
, *i
, presets
, changes
, n_changes
);
2809 return execute_preset(scope
, &plus
, &minus
, &paths
, config_path
, files
, mode
, force
, changes
, n_changes
);
2812 int unit_file_preset_all(
2813 UnitFileScope scope
,
2815 const char *root_dir
,
2816 UnitFilePresetMode mode
,
2818 UnitFileChange
**changes
,
2819 unsigned *n_changes
) {
2821 _cleanup_(install_context_done
) InstallContext plus
= {}, minus
= {};
2822 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2823 _cleanup_(presets_freep
) Presets presets
= {};
2824 const char *config_path
= NULL
;
2829 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2830 assert(mode
< _UNIT_FILE_PRESET_MAX
);
2832 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2836 config_path
= runtime
? paths
.runtime_config
: paths
.persistent_config
;
2838 r
= read_presets(scope
, root_dir
, &presets
);
2842 STRV_FOREACH(i
, paths
.search_path
) {
2843 _cleanup_closedir_
DIR *d
= NULL
;
2848 if (errno
== ENOENT
)
2854 FOREACH_DIRENT(de
, d
, return -errno
) {
2856 if (!unit_name_is_valid(de
->d_name
, UNIT_NAME_ANY
))
2859 dirent_ensure_type(d
, de
);
2861 if (!IN_SET(de
->d_type
, DT_LNK
, DT_REG
))
2864 /* we don't pass changes[] in, because we want to handle errors on our own */
2865 r
= preset_prepare_one(scope
, &plus
, &minus
, &paths
, de
->d_name
, presets
, NULL
, 0);
2867 r
= unit_file_changes_add(changes
, n_changes
,
2868 UNIT_FILE_IS_MASKED
, de
->d_name
, NULL
);
2869 else if (r
== -ENOLINK
)
2870 r
= unit_file_changes_add(changes
, n_changes
,
2871 UNIT_FILE_IS_DANGLING
, de
->d_name
, NULL
);
2877 return execute_preset(scope
, &plus
, &minus
, &paths
, config_path
, NULL
, mode
, force
, changes
, n_changes
);
2880 static void unit_file_list_free_one(UnitFileList
*f
) {
2888 Hashmap
* unit_file_list_free(Hashmap
*h
) {
2891 while ((i
= hashmap_steal_first(h
)))
2892 unit_file_list_free_one(i
);
2894 return hashmap_free(h
);
2897 DEFINE_TRIVIAL_CLEANUP_FUNC(UnitFileList
*, unit_file_list_free_one
);
2899 int unit_file_get_list(
2900 UnitFileScope scope
,
2901 const char *root_dir
,
2906 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2911 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2914 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2918 STRV_FOREACH(i
, paths
.search_path
) {
2919 _cleanup_closedir_
DIR *d
= NULL
;
2924 if (errno
== ENOENT
)
2926 if (IN_SET(errno
, ENOTDIR
, EACCES
)) {
2927 log_debug("Failed to open \"%s\": %m", *i
);
2934 FOREACH_DIRENT(de
, d
, return -errno
) {
2935 _cleanup_(unit_file_list_free_onep
) UnitFileList
*f
= NULL
;
2937 if (!unit_name_is_valid(de
->d_name
, UNIT_NAME_ANY
))
2940 if (!strv_fnmatch_or_empty(patterns
, de
->d_name
, FNM_NOESCAPE
))
2943 if (hashmap_get(h
, de
->d_name
))
2946 dirent_ensure_type(d
, de
);
2948 if (!IN_SET(de
->d_type
, DT_LNK
, DT_REG
))
2951 f
= new0(UnitFileList
, 1);
2955 f
->path
= path_make_absolute(de
->d_name
, *i
);
2959 r
= unit_file_lookup_state(scope
, &paths
, de
->d_name
, &f
->state
);
2961 f
->state
= UNIT_FILE_BAD
;
2963 if (!strv_isempty(states
) &&
2964 !strv_contains(states
, unit_file_state_to_string(f
->state
)))
2967 r
= hashmap_put(h
, basename(f
->path
), f
);
2971 f
= NULL
; /* prevent cleanup */
2978 static const char* const unit_file_state_table
[_UNIT_FILE_STATE_MAX
] = {
2979 [UNIT_FILE_ENABLED
] = "enabled",
2980 [UNIT_FILE_ENABLED_RUNTIME
] = "enabled-runtime",
2981 [UNIT_FILE_LINKED
] = "linked",
2982 [UNIT_FILE_LINKED_RUNTIME
] = "linked-runtime",
2983 [UNIT_FILE_MASKED
] = "masked",
2984 [UNIT_FILE_MASKED_RUNTIME
] = "masked-runtime",
2985 [UNIT_FILE_STATIC
] = "static",
2986 [UNIT_FILE_DISABLED
] = "disabled",
2987 [UNIT_FILE_INDIRECT
] = "indirect",
2988 [UNIT_FILE_GENERATED
] = "generated",
2989 [UNIT_FILE_TRANSIENT
] = "transient",
2990 [UNIT_FILE_BAD
] = "bad",
2993 DEFINE_STRING_TABLE_LOOKUP(unit_file_state
, UnitFileState
);
2995 static const char* const unit_file_change_type_table
[_UNIT_FILE_CHANGE_TYPE_MAX
] = {
2996 [UNIT_FILE_SYMLINK
] = "symlink",
2997 [UNIT_FILE_UNLINK
] = "unlink",
2998 [UNIT_FILE_IS_MASKED
] = "masked",
2999 [UNIT_FILE_IS_DANGLING
] = "dangling",
3002 DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type
, UnitFileChangeType
);
3004 static const char* const unit_file_preset_mode_table
[_UNIT_FILE_PRESET_MAX
] = {
3005 [UNIT_FILE_PRESET_FULL
] = "full",
3006 [UNIT_FILE_PRESET_ENABLE_ONLY
] = "enable-only",
3007 [UNIT_FILE_PRESET_DISABLE_ONLY
] = "disable-only",
3010 DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode
, UnitFilePresetMode
);