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
,
523 UnitFileChange
**changes
,
524 unsigned *n_changes
) {
526 _cleanup_closedir_
DIR *d
= NULL
;
530 assert(remove_symlinks_to
);
545 FOREACH_DIRENT(de
, d
, return -errno
) {
547 dirent_ensure_type(d
, de
);
549 if (de
->d_type
== DT_DIR
) {
550 _cleanup_free_
char *p
= NULL
;
553 nfd
= openat(fd
, de
->d_name
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
|O_NOFOLLOW
);
563 p
= path_make_absolute(de
->d_name
, path
);
569 /* This will close nfd, regardless whether it succeeds or not */
570 q
= remove_marked_symlinks_fd(remove_symlinks_to
, nfd
, p
, config_path
, lp
, dry_run
, restart
, changes
, n_changes
);
574 } else if (de
->d_type
== DT_LNK
) {
575 _cleanup_free_
char *p
= NULL
, *dest
= NULL
;
580 if (!unit_name_is_valid(de
->d_name
, UNIT_NAME_ANY
))
583 p
= path_make_absolute(de
->d_name
, path
);
586 path_kill_slashes(p
);
588 q
= readlink_malloc(p
, &dest
);
597 /* We remove all links pointing to a file or path that is marked, as well as all files sharing
598 * the same name as a file that is marked. */
600 found
= set_contains(remove_symlinks_to
, dest
) ||
601 set_contains(remove_symlinks_to
, basename(dest
)) ||
602 set_contains(remove_symlinks_to
, de
->d_name
);
608 if (unlinkat(fd
, de
->d_name
, 0) < 0 && errno
!= ENOENT
) {
611 unit_file_changes_add(changes
, n_changes
, -errno
, p
, NULL
);
615 (void) rmdir_parents(p
, config_path
);
618 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_UNLINK
, p
, NULL
);
620 /* Now, remember the full path (but with the root prefix removed) of
621 * the symlink we just removed, and remove any symlinks to it, too. */
623 rp
= skip_root(lp
, p
);
624 q
= mark_symlink_for_removal(&remove_symlinks_to
, rp
?: p
);
627 if (q
> 0 && !dry_run
)
635 static int remove_marked_symlinks(
636 Set
*remove_symlinks_to
,
637 const char *config_path
,
638 const LookupPaths
*lp
,
640 UnitFileChange
**changes
,
641 unsigned *n_changes
) {
643 _cleanup_close_
int fd
= -1;
650 if (set_size(remove_symlinks_to
) <= 0)
653 fd
= open(config_path
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
);
655 return errno
== ENOENT
? 0 : -errno
;
661 cfd
= fcntl(fd
, F_DUPFD_CLOEXEC
, 3);
665 /* This takes possession of cfd and closes it */
666 q
= remove_marked_symlinks_fd(remove_symlinks_to
, cfd
, config_path
, config_path
, lp
, dry_run
, &restart
, changes
, n_changes
);
674 static int find_symlinks_fd(
675 const char *root_dir
,
679 const char *config_path
,
680 const LookupPaths
*lp
,
681 bool *same_name_link
) {
683 _cleanup_closedir_
DIR *d
= NULL
;
692 assert(same_name_link
);
700 FOREACH_DIRENT(de
, d
, return -errno
) {
702 dirent_ensure_type(d
, de
);
704 if (de
->d_type
== DT_DIR
) {
705 _cleanup_free_
char *p
= NULL
;
708 nfd
= openat(fd
, de
->d_name
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
|O_NOFOLLOW
);
718 p
= path_make_absolute(de
->d_name
, path
);
724 /* This will close nfd, regardless whether it succeeds or not */
725 q
= find_symlinks_fd(root_dir
, name
, nfd
, p
, config_path
, lp
, same_name_link
);
731 } else if (de
->d_type
== DT_LNK
) {
732 _cleanup_free_
char *p
= NULL
, *dest
= NULL
;
733 bool found_path
, found_dest
, b
= false;
736 /* Acquire symlink name */
737 p
= path_make_absolute(de
->d_name
, path
);
741 /* Acquire symlink destination */
742 q
= readlink_malloc(p
, &dest
);
752 if (!path_is_absolute(dest
)) {
755 x
= prefix_root(root_dir
, dest
);
763 /* Check if the symlink itself matches what we
765 if (path_is_absolute(name
))
766 found_path
= path_equal(p
, name
);
768 found_path
= streq(de
->d_name
, name
);
770 /* Check if what the symlink points to
771 * matches what we are looking for */
772 if (path_is_absolute(name
))
773 found_dest
= path_equal(dest
, name
);
775 found_dest
= streq(basename(dest
), name
);
777 if (found_path
&& found_dest
) {
778 _cleanup_free_
char *t
= NULL
;
780 /* Filter out same name links in the main
782 t
= path_make_absolute(name
, config_path
);
786 b
= path_equal(t
, p
);
790 *same_name_link
= true;
791 else if (found_path
|| found_dest
)
799 static int find_symlinks(
800 const char *root_dir
,
802 const char *config_path
,
803 const LookupPaths
*lp
,
804 bool *same_name_link
) {
810 assert(same_name_link
);
812 fd
= open(config_path
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
);
814 if (IN_SET(errno
, ENOENT
, ENOTDIR
, EACCES
))
819 /* This takes possession of fd and closes it */
820 return find_symlinks_fd(root_dir
, name
, fd
, config_path
, config_path
, lp
, same_name_link
);
823 static int find_symlinks_in_scope(
825 const LookupPaths
*paths
,
827 UnitFileState
*state
) {
829 bool same_name_link_runtime
= false, same_name_link
= false;
833 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
837 /* First look in the persistent config path */
838 r
= find_symlinks(paths
->root_dir
, name
, paths
->persistent_config
, paths
, &same_name_link
);
842 *state
= UNIT_FILE_ENABLED
;
846 /* Then look in runtime config path */
847 r
= find_symlinks(paths
->root_dir
, name
, paths
->runtime_config
, paths
, &same_name_link_runtime
);
851 *state
= UNIT_FILE_ENABLED_RUNTIME
;
855 /* Hmm, we didn't find it, but maybe we found the same name
857 if (same_name_link
) {
858 *state
= UNIT_FILE_LINKED
;
861 if (same_name_link_runtime
) {
862 *state
= UNIT_FILE_LINKED_RUNTIME
;
869 static void install_info_free(UnitFileInstallInfo
*i
) {
876 strv_free(i
->aliases
);
877 strv_free(i
->wanted_by
);
878 strv_free(i
->required_by
);
880 free(i
->default_instance
);
881 free(i
->symlink_target
);
885 static OrderedHashmap
* install_info_hashmap_free(OrderedHashmap
*m
) {
886 UnitFileInstallInfo
*i
;
891 while ((i
= ordered_hashmap_steal_first(m
)))
892 install_info_free(i
);
894 return ordered_hashmap_free(m
);
897 static void install_context_done(InstallContext
*c
) {
900 c
->will_process
= install_info_hashmap_free(c
->will_process
);
901 c
->have_processed
= install_info_hashmap_free(c
->have_processed
);
904 static UnitFileInstallInfo
*install_info_find(InstallContext
*c
, const char *name
) {
905 UnitFileInstallInfo
*i
;
907 i
= ordered_hashmap_get(c
->have_processed
, name
);
911 return ordered_hashmap_get(c
->will_process
, name
);
914 static int install_info_may_process(
915 UnitFileInstallInfo
*i
,
916 const LookupPaths
*paths
,
917 UnitFileChange
**changes
,
918 unsigned *n_changes
) {
922 /* Checks whether the loaded unit file is one we should process, or is masked,
923 * transient or generated and thus not subject to enable/disable operations. */
925 if (i
->type
== UNIT_FILE_TYPE_MASKED
) {
926 unit_file_changes_add(changes
, n_changes
, -ERFKILL
, i
->path
, NULL
);
929 if (path_is_generator(paths
, i
->path
) ||
930 path_is_transient(paths
, i
->path
)) {
931 unit_file_changes_add(changes
, n_changes
, -EADDRNOTAVAIL
, i
->path
, NULL
);
932 return -EADDRNOTAVAIL
;
939 * Adds a new UnitFileInstallInfo entry under name in the InstallContext.will_process
940 * hashmap, or retrieves the existing one if already present.
942 * Returns negative on error, 0 if the unit was already known, 1 otherwise.
944 static int install_info_add(
949 UnitFileInstallInfo
**ret
) {
951 UnitFileInstallInfo
*i
= NULL
;
955 assert(name
|| path
);
958 name
= basename(path
);
960 if (!unit_name_is_valid(name
, UNIT_NAME_ANY
))
963 i
= install_info_find(c
, name
);
965 i
->auxiliary
= i
->auxiliary
&& auxiliary
;
972 r
= ordered_hashmap_ensure_allocated(&c
->will_process
, &string_hash_ops
);
976 i
= new0(UnitFileInstallInfo
, 1);
979 i
->type
= _UNIT_FILE_TYPE_INVALID
;
980 i
->auxiliary
= auxiliary
;
982 i
->name
= strdup(name
);
989 i
->path
= strdup(path
);
996 r
= ordered_hashmap_put(c
->will_process
, i
->name
, i
);
1006 install_info_free(i
);
1010 static int config_parse_alias(
1012 const char *filename
,
1014 const char *section
,
1015 unsigned section_line
,
1029 name
= basename(filename
);
1030 type
= unit_name_to_type(name
);
1031 if (!unit_type_may_alias(type
))
1032 return log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1033 "Alias= is not allowed for %s units, ignoring.",
1034 unit_type_to_string(type
));
1036 return config_parse_strv(unit
, filename
, line
, section
, section_line
,
1037 lvalue
, ltype
, rvalue
, data
, userdata
);
1040 static int config_parse_also(
1042 const char *filename
,
1044 const char *section
,
1045 unsigned section_line
,
1052 UnitFileInstallInfo
*info
= userdata
, *alsoinfo
= NULL
;
1053 InstallContext
*c
= data
;
1061 _cleanup_free_
char *word
= NULL
, *printed
= NULL
;
1063 r
= extract_first_word(&rvalue
, &word
, NULL
, 0);
1069 r
= install_full_printf(info
, word
, &printed
);
1073 if (!unit_name_is_valid(printed
, UNIT_NAME_ANY
))
1076 r
= install_info_add(c
, printed
, NULL
, true, &alsoinfo
);
1080 r
= strv_push(&info
->also
, printed
);
1090 static int config_parse_default_instance(
1092 const char *filename
,
1094 const char *section
,
1095 unsigned section_line
,
1102 UnitFileInstallInfo
*i
= data
;
1104 _cleanup_free_
char *printed
= NULL
;
1111 name
= basename(filename
);
1112 if (unit_name_is_valid(name
, UNIT_NAME_INSTANCE
))
1113 /* When enabling an instance, we might be using a template unit file,
1114 * but we should ignore DefaultInstance silently. */
1116 if (!unit_name_is_valid(name
, UNIT_NAME_TEMPLATE
))
1117 return log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1118 "DefaultInstance= only makes sense for template units, ignoring.");
1120 r
= install_full_printf(i
, rvalue
, &printed
);
1124 if (!unit_instance_is_valid(printed
))
1127 return free_and_replace(i
->default_instance
, printed
);
1130 static int unit_file_load(
1132 UnitFileInstallInfo
*info
,
1134 SearchFlags flags
) {
1136 const ConfigTableItem items
[] = {
1137 { "Install", "Alias", config_parse_alias
, 0, &info
->aliases
},
1138 { "Install", "WantedBy", config_parse_strv
, 0, &info
->wanted_by
},
1139 { "Install", "RequiredBy", config_parse_strv
, 0, &info
->required_by
},
1140 { "Install", "DefaultInstance", config_parse_default_instance
, 0, info
},
1141 { "Install", "Also", config_parse_also
, 0, c
},
1147 _cleanup_fclose_
FILE *f
= NULL
;
1148 _cleanup_close_
int fd
= -1;
1155 name
= basename(path
);
1156 type
= unit_name_to_type(name
);
1157 if (unit_name_is_valid(name
, UNIT_NAME_TEMPLATE
|UNIT_NAME_INSTANCE
) &&
1158 !unit_type_may_template(type
))
1159 return log_error_errno(EINVAL
, "Unit type %s cannot be templated.", unit_type_to_string(type
));
1161 if (!(flags
& SEARCH_LOAD
)) {
1162 r
= lstat(path
, &st
);
1166 if (null_or_empty(&st
))
1167 info
->type
= UNIT_FILE_TYPE_MASKED
;
1168 else if (S_ISREG(st
.st_mode
))
1169 info
->type
= UNIT_FILE_TYPE_REGULAR
;
1170 else if (S_ISLNK(st
.st_mode
))
1172 else if (S_ISDIR(st
.st_mode
))
1180 /* c is only needed if we actually load the file */
1183 fd
= open(path
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
|O_NOFOLLOW
);
1186 if (fstat(fd
, &st
) < 0)
1188 if (null_or_empty(&st
)) {
1189 info
->type
= UNIT_FILE_TYPE_MASKED
;
1192 if (S_ISDIR(st
.st_mode
))
1194 if (!S_ISREG(st
.st_mode
))
1197 f
= fdopen(fd
, "re");
1202 r
= config_parse(NULL
, path
, f
,
1204 config_item_table_lookup
, items
,
1205 true, true, false, info
);
1207 return log_debug_errno(r
, "Failed to parse %s: %m", info
->name
);
1209 info
->type
= UNIT_FILE_TYPE_REGULAR
;
1212 (int) strv_length(info
->aliases
) +
1213 (int) strv_length(info
->wanted_by
) +
1214 (int) strv_length(info
->required_by
);
1217 static int unit_file_load_or_readlink(
1219 UnitFileInstallInfo
*info
,
1221 const char *root_dir
,
1222 SearchFlags flags
) {
1224 _cleanup_free_
char *target
= NULL
;
1227 r
= unit_file_load(c
, info
, path
, flags
);
1231 /* This is a symlink, let's read it. */
1233 r
= readlink_malloc(path
, &target
);
1237 if (path_equal(target
, "/dev/null"))
1238 info
->type
= UNIT_FILE_TYPE_MASKED
;
1243 bn
= basename(target
);
1245 if (unit_name_is_valid(info
->name
, UNIT_NAME_PLAIN
)) {
1247 if (!unit_name_is_valid(bn
, UNIT_NAME_PLAIN
))
1250 } else if (unit_name_is_valid(info
->name
, UNIT_NAME_INSTANCE
)) {
1252 if (!unit_name_is_valid(bn
, UNIT_NAME_INSTANCE
|UNIT_NAME_TEMPLATE
))
1255 } else if (unit_name_is_valid(info
->name
, UNIT_NAME_TEMPLATE
)) {
1257 if (!unit_name_is_valid(bn
, UNIT_NAME_TEMPLATE
))
1262 /* Enforce that the symlink destination does not
1263 * change the unit file type. */
1265 a
= unit_name_to_type(info
->name
);
1266 b
= unit_name_to_type(bn
);
1267 if (a
< 0 || b
< 0 || a
!= b
)
1270 if (path_is_absolute(target
))
1271 /* This is an absolute path, prefix the root so that we always deal with fully qualified paths */
1272 info
->symlink_target
= prefix_root(root_dir
, target
);
1274 /* This is a relative path, take it relative to the dir the symlink is located in. */
1275 info
->symlink_target
= file_in_same_dir(path
, target
);
1276 if (!info
->symlink_target
)
1279 info
->type
= UNIT_FILE_TYPE_SYMLINK
;
1285 static int unit_file_search(
1287 UnitFileInstallInfo
*info
,
1288 const LookupPaths
*paths
,
1289 SearchFlags flags
) {
1291 _cleanup_free_
char *template = NULL
;
1298 /* Was this unit already loaded? */
1299 if (info
->type
!= _UNIT_FILE_TYPE_INVALID
)
1303 return unit_file_load_or_readlink(c
, info
, info
->path
, paths
->root_dir
, flags
);
1307 STRV_FOREACH(p
, paths
->search_path
) {
1308 _cleanup_free_
char *path
= NULL
;
1310 path
= strjoin(*p
, "/", info
->name
);
1314 r
= unit_file_load_or_readlink(c
, info
, path
, paths
->root_dir
, flags
);
1319 } else if (!IN_SET(r
, -ENOENT
, -ENOTDIR
, -EACCES
))
1323 if (unit_name_is_valid(info
->name
, UNIT_NAME_INSTANCE
)) {
1324 /* Unit file doesn't exist, however instance
1325 * enablement was requested. We will check if it is
1326 * possible to load template unit file. */
1328 r
= unit_name_template(info
->name
, &template);
1332 STRV_FOREACH(p
, paths
->search_path
) {
1333 _cleanup_free_
char *path
= NULL
;
1335 path
= strjoin(*p
, "/", template);
1339 r
= unit_file_load_or_readlink(c
, info
, path
, paths
->root_dir
, flags
);
1344 } else if (!IN_SET(r
, -ENOENT
, -ENOTDIR
, -EACCES
))
1349 log_debug("Cannot find unit %s%s%s.", info
->name
, template ? " or " : "", strempty(template));
1353 static int install_info_follow(
1355 UnitFileInstallInfo
*i
,
1356 const char *root_dir
,
1357 SearchFlags flags
) {
1362 if (i
->type
!= UNIT_FILE_TYPE_SYMLINK
)
1364 if (!i
->symlink_target
)
1367 /* If the basename doesn't match, the caller should add a
1368 * complete new entry for this. */
1370 if (!streq(basename(i
->symlink_target
), i
->name
))
1373 free_and_replace(i
->path
, i
->symlink_target
);
1374 i
->type
= _UNIT_FILE_TYPE_INVALID
;
1376 return unit_file_load_or_readlink(c
, i
, i
->path
, root_dir
, flags
);
1380 * Search for the unit file. If the unit name is a symlink, follow the symlink to the
1381 * target, maybe more than once. Propagate the instance name if present.
1383 static int install_info_traverse(
1384 UnitFileScope scope
,
1386 const LookupPaths
*paths
,
1387 UnitFileInstallInfo
*start
,
1389 UnitFileInstallInfo
**ret
) {
1391 UnitFileInstallInfo
*i
;
1399 r
= unit_file_search(c
, start
, paths
, flags
);
1404 while (i
->type
== UNIT_FILE_TYPE_SYMLINK
) {
1405 /* Follow the symlink */
1407 if (++k
> UNIT_FILE_FOLLOW_SYMLINK_MAX
)
1410 if (!(flags
& SEARCH_FOLLOW_CONFIG_SYMLINKS
)) {
1411 r
= path_is_config(paths
, i
->path
);
1418 r
= install_info_follow(c
, i
, paths
->root_dir
, flags
);
1420 _cleanup_free_
char *buffer
= NULL
;
1423 /* Target has a different name, create a new
1424 * install info object for that, and continue
1427 bn
= basename(i
->symlink_target
);
1429 if (unit_name_is_valid(i
->name
, UNIT_NAME_INSTANCE
) &&
1430 unit_name_is_valid(bn
, UNIT_NAME_TEMPLATE
)) {
1432 _cleanup_free_
char *instance
= NULL
;
1434 r
= unit_name_to_instance(i
->name
, &instance
);
1438 r
= unit_name_replace_instance(bn
, instance
, &buffer
);
1445 r
= install_info_add(c
, bn
, NULL
, false, &i
);
1449 /* Try again, with the new target we found. */
1450 r
= unit_file_search(c
, i
, paths
, flags
);
1452 /* Translate error code to highlight this specific case */
1467 * Call install_info_add() with name_or_path as the path (if name_or_path starts with "/")
1468 * or the name (otherwise). root_dir is prepended to the path.
1470 static int install_info_add_auto(
1472 const LookupPaths
*paths
,
1473 const char *name_or_path
,
1474 UnitFileInstallInfo
**ret
) {
1477 assert(name_or_path
);
1479 if (path_is_absolute(name_or_path
)) {
1482 pp
= prefix_roota(paths
->root_dir
, name_or_path
);
1484 return install_info_add(c
, NULL
, pp
, false, ret
);
1486 return install_info_add(c
, name_or_path
, NULL
, false, ret
);
1489 static int install_info_discover(
1490 UnitFileScope scope
,
1492 const LookupPaths
*paths
,
1495 UnitFileInstallInfo
**ret
,
1496 UnitFileChange
**changes
,
1497 unsigned *n_changes
) {
1499 UnitFileInstallInfo
*i
;
1506 r
= install_info_add_auto(c
, paths
, name
, &i
);
1508 r
= install_info_traverse(scope
, c
, paths
, i
, flags
, ret
);
1511 unit_file_changes_add(changes
, n_changes
, r
, name
, NULL
);
1515 static int install_info_symlink_alias(
1516 UnitFileInstallInfo
*i
,
1517 const LookupPaths
*paths
,
1518 const char *config_path
,
1520 UnitFileChange
**changes
,
1521 unsigned *n_changes
) {
1528 assert(config_path
);
1530 STRV_FOREACH(s
, i
->aliases
) {
1531 _cleanup_free_
char *alias_path
= NULL
, *dst
= NULL
;
1533 q
= install_full_printf(i
, *s
, &dst
);
1537 alias_path
= path_make_absolute(dst
, config_path
);
1541 q
= create_symlink(paths
, i
->path
, alias_path
, force
, changes
, n_changes
);
1549 static int install_info_symlink_wants(
1550 UnitFileInstallInfo
*i
,
1551 const LookupPaths
*paths
,
1552 const char *config_path
,
1555 UnitFileChange
**changes
,
1556 unsigned *n_changes
) {
1558 _cleanup_free_
char *buf
= NULL
;
1565 assert(config_path
);
1567 if (strv_isempty(list
))
1570 if (unit_name_is_valid(i
->name
, UNIT_NAME_TEMPLATE
) && i
->default_instance
) {
1571 UnitFileInstallInfo instance
= {
1572 .type
= _UNIT_FILE_TYPE_INVALID
,
1574 _cleanup_free_
char *path
= NULL
;
1576 r
= unit_name_replace_instance(i
->name
, i
->default_instance
, &buf
);
1580 instance
.name
= buf
;
1581 r
= unit_file_search(NULL
, &instance
, paths
, SEARCH_FOLLOW_CONFIG_SYMLINKS
);
1585 path
= instance
.path
;
1586 instance
.path
= NULL
;
1588 if (instance
.type
== UNIT_FILE_TYPE_MASKED
) {
1589 unit_file_changes_add(changes
, n_changes
, -ERFKILL
, path
, NULL
);
1597 STRV_FOREACH(s
, list
) {
1598 _cleanup_free_
char *path
= NULL
, *dst
= NULL
;
1600 q
= install_full_printf(i
, *s
, &dst
);
1604 if (!unit_name_is_valid(dst
, UNIT_NAME_ANY
)) {
1609 path
= strjoin(config_path
, "/", dst
, suffix
, n
);
1613 q
= create_symlink(paths
, i
->path
, path
, true, changes
, n_changes
);
1621 static int install_info_symlink_link(
1622 UnitFileInstallInfo
*i
,
1623 const LookupPaths
*paths
,
1624 const char *config_path
,
1626 UnitFileChange
**changes
,
1627 unsigned *n_changes
) {
1629 _cleanup_free_
char *path
= NULL
;
1634 assert(config_path
);
1637 r
= in_search_path(paths
, i
->path
);
1643 path
= strjoin(config_path
, "/", i
->name
);
1647 return create_symlink(paths
, i
->path
, path
, force
, changes
, n_changes
);
1650 static int install_info_apply(
1651 UnitFileInstallInfo
*i
,
1652 const LookupPaths
*paths
,
1653 const char *config_path
,
1655 UnitFileChange
**changes
,
1656 unsigned *n_changes
) {
1662 assert(config_path
);
1664 if (i
->type
!= UNIT_FILE_TYPE_REGULAR
)
1667 r
= install_info_symlink_alias(i
, paths
, config_path
, force
, changes
, n_changes
);
1669 q
= install_info_symlink_wants(i
, paths
, config_path
, i
->wanted_by
, ".wants/", changes
, n_changes
);
1673 q
= install_info_symlink_wants(i
, paths
, config_path
, i
->required_by
, ".requires/", changes
, n_changes
);
1677 q
= install_info_symlink_link(i
, paths
, config_path
, force
, changes
, n_changes
);
1678 /* Do not count links to the unit file towards the "carries_install_info" count */
1679 if (r
== 0 && q
< 0)
1685 static int install_context_apply(
1686 UnitFileScope scope
,
1688 const LookupPaths
*paths
,
1689 const char *config_path
,
1692 UnitFileChange
**changes
,
1693 unsigned *n_changes
) {
1695 UnitFileInstallInfo
*i
;
1700 assert(config_path
);
1702 if (ordered_hashmap_isempty(c
->will_process
))
1705 r
= ordered_hashmap_ensure_allocated(&c
->have_processed
, &string_hash_ops
);
1710 while ((i
= ordered_hashmap_first(c
->will_process
))) {
1713 q
= ordered_hashmap_move_one(c
->have_processed
, c
->will_process
, i
->name
);
1717 r
= install_info_traverse(scope
, c
, paths
, i
, flags
, NULL
);
1719 unit_file_changes_add(changes
, n_changes
, r
, i
->name
, NULL
);
1723 /* We can attempt to process a masked unit when a different unit
1724 * that we were processing specifies it in Also=. */
1725 if (i
->type
== UNIT_FILE_TYPE_MASKED
) {
1726 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_IS_MASKED
, i
->path
, NULL
);
1728 /* Assume that something *could* have been enabled here,
1729 * avoid "empty [Install] section" warning. */
1734 if (i
->type
!= UNIT_FILE_TYPE_REGULAR
)
1737 q
= install_info_apply(i
, paths
, config_path
, force
, changes
, n_changes
);
1749 static int install_context_mark_for_removal(
1750 UnitFileScope scope
,
1752 const LookupPaths
*paths
,
1753 Set
**remove_symlinks_to
,
1754 const char *config_path
) {
1756 UnitFileInstallInfo
*i
;
1761 assert(config_path
);
1763 /* Marks all items for removal */
1765 if (ordered_hashmap_isempty(c
->will_process
))
1768 r
= ordered_hashmap_ensure_allocated(&c
->have_processed
, &string_hash_ops
);
1772 while ((i
= ordered_hashmap_first(c
->will_process
))) {
1774 r
= ordered_hashmap_move_one(c
->have_processed
, c
->will_process
, i
->name
);
1778 r
= install_info_traverse(scope
, c
, paths
, i
, SEARCH_LOAD
|SEARCH_FOLLOW_CONFIG_SYMLINKS
, NULL
);
1779 if (r
== -ENOLINK
) {
1780 log_debug_errno(r
, "Name %s leads to a dangling symlink, ignoring.", i
->name
);
1782 } else if (r
== -ENOENT
&& i
->auxiliary
) {
1783 /* some unit specified in Also= or similar is missing */
1784 log_debug_errno(r
, "Auxiliary unit %s not found, ignoring.", i
->name
);
1787 return log_debug_errno(r
, "Failed to find unit %s: %m", i
->name
);
1789 if (i
->type
!= UNIT_FILE_TYPE_REGULAR
) {
1790 log_debug("Unit %s has type %s, ignoring.",
1792 unit_file_type_to_string(i
->type
) ?: "invalid");
1796 r
= mark_symlink_for_removal(remove_symlinks_to
, i
->name
);
1805 UnitFileScope scope
,
1806 UnitFileFlags flags
,
1807 const char *root_dir
,
1809 UnitFileChange
**changes
,
1810 unsigned *n_changes
) {
1812 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
1813 const char *config_path
;
1818 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
1820 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
1824 config_path
= (flags
& UNIT_FILE_RUNTIME
) ? paths
.runtime_config
: paths
.persistent_config
;
1826 STRV_FOREACH(i
, files
) {
1827 _cleanup_free_
char *path
= NULL
;
1830 if (!unit_name_is_valid(*i
, UNIT_NAME_ANY
)) {
1836 path
= path_make_absolute(*i
, config_path
);
1840 q
= create_symlink(&paths
, "/dev/null", path
, !!(flags
& UNIT_FILE_FORCE
), changes
, n_changes
);
1841 if (q
< 0 && r
>= 0)
1848 int unit_file_unmask(
1849 UnitFileScope scope
,
1850 UnitFileFlags flags
,
1851 const char *root_dir
,
1853 UnitFileChange
**changes
,
1854 unsigned *n_changes
) {
1856 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
1857 _cleanup_set_free_free_ Set
*remove_symlinks_to
= NULL
;
1858 _cleanup_free_
char **todo
= NULL
;
1859 size_t n_todo
= 0, n_allocated
= 0;
1860 const char *config_path
;
1866 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
1868 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
1872 config_path
= (flags
& UNIT_FILE_RUNTIME
) ? paths
.runtime_config
: paths
.persistent_config
;
1873 dry_run
= !!(flags
& UNIT_FILE_DRY_RUN
);
1875 STRV_FOREACH(i
, files
) {
1876 _cleanup_free_
char *path
= NULL
;
1878 if (!unit_name_is_valid(*i
, UNIT_NAME_ANY
))
1881 path
= path_make_absolute(*i
, config_path
);
1885 r
= null_or_empty_path(path
);
1893 if (!GREEDY_REALLOC0(todo
, n_allocated
, n_todo
+ 2))
1896 todo
[n_todo
++] = *i
;
1902 STRV_FOREACH(i
, todo
) {
1903 _cleanup_free_
char *path
= NULL
;
1906 path
= path_make_absolute(*i
, config_path
);
1910 if (!dry_run
&& unlink(path
) < 0) {
1911 if (errno
!= ENOENT
) {
1914 unit_file_changes_add(changes
, n_changes
, -errno
, path
, NULL
);
1920 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_UNLINK
, path
, NULL
);
1922 rp
= skip_root(&paths
, path
);
1923 q
= mark_symlink_for_removal(&remove_symlinks_to
, rp
?: path
);
1928 q
= remove_marked_symlinks(remove_symlinks_to
, config_path
, &paths
, dry_run
, changes
, n_changes
);
1936 UnitFileScope scope
,
1937 UnitFileFlags flags
,
1938 const char *root_dir
,
1940 UnitFileChange
**changes
,
1941 unsigned *n_changes
) {
1943 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
1944 _cleanup_free_
char **todo
= NULL
;
1945 size_t n_todo
= 0, n_allocated
= 0;
1946 const char *config_path
;
1951 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
1953 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
1957 config_path
= (flags
& UNIT_FILE_RUNTIME
) ? paths
.runtime_config
: paths
.persistent_config
;
1959 STRV_FOREACH(i
, files
) {
1960 _cleanup_free_
char *full
= NULL
;
1964 if (!path_is_absolute(*i
))
1968 if (!unit_name_is_valid(fn
, UNIT_NAME_ANY
))
1971 full
= prefix_root(paths
.root_dir
, *i
);
1975 if (lstat(full
, &st
) < 0)
1977 if (S_ISLNK(st
.st_mode
))
1979 if (S_ISDIR(st
.st_mode
))
1981 if (!S_ISREG(st
.st_mode
))
1984 q
= in_search_path(&paths
, *i
);
1990 if (!GREEDY_REALLOC0(todo
, n_allocated
, n_todo
+ 2))
1993 todo
[n_todo
++] = *i
;
1999 STRV_FOREACH(i
, todo
) {
2000 _cleanup_free_
char *new_path
= NULL
;
2002 new_path
= path_make_absolute(basename(*i
), config_path
);
2006 q
= create_symlink(&paths
, *i
, new_path
, !!(flags
& UNIT_FILE_FORCE
), changes
, n_changes
);
2007 if (q
< 0 && r
>= 0)
2014 static int path_shall_revert(const LookupPaths
*paths
, const char *path
) {
2020 /* Checks whether the path is one where the drop-in directories shall be removed. */
2022 r
= path_is_config(paths
, path
);
2026 r
= path_is_control(paths
, path
);
2030 return path_is_transient(paths
, path
);
2033 int unit_file_revert(
2034 UnitFileScope scope
,
2035 const char *root_dir
,
2037 UnitFileChange
**changes
,
2038 unsigned *n_changes
) {
2040 _cleanup_set_free_free_ Set
*remove_symlinks_to
= NULL
;
2041 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2042 _cleanup_strv_free_
char **todo
= NULL
;
2043 size_t n_todo
= 0, n_allocated
= 0;
2047 /* Puts a unit file back into vendor state. This means:
2049 * a) we remove all drop-in snippets added by the user ("config"), add to transient units ("transient"), and
2050 * added via "systemctl set-property" ("control"), but not if the drop-in is generated ("generated").
2052 * c) if there's a vendor unit file (i.e. one in /usr) we remove any configured overriding unit files (i.e. in
2053 * "config", but not in "transient" or "control" or even "generated").
2055 * We remove all that in both the runtime and the persistent directories, if that applies.
2058 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2062 STRV_FOREACH(i
, files
) {
2063 bool has_vendor
= false;
2066 if (!unit_name_is_valid(*i
, UNIT_NAME_ANY
))
2069 STRV_FOREACH(p
, paths
.search_path
) {
2070 _cleanup_free_
char *path
= NULL
, *dropin
= NULL
;
2073 path
= path_make_absolute(*i
, *p
);
2077 r
= lstat(path
, &st
);
2079 if (errno
!= ENOENT
)
2081 } else if (S_ISREG(st
.st_mode
)) {
2082 /* Check if there's a vendor version */
2083 r
= path_is_vendor(&paths
, path
);
2090 dropin
= strappend(path
, ".d");
2094 r
= lstat(dropin
, &st
);
2096 if (errno
!= ENOENT
)
2098 } else if (S_ISDIR(st
.st_mode
)) {
2099 /* Remove the drop-ins */
2100 r
= path_shall_revert(&paths
, dropin
);
2104 if (!GREEDY_REALLOC0(todo
, n_allocated
, n_todo
+ 2))
2107 todo
[n_todo
++] = dropin
;
2116 /* OK, there's a vendor version, hence drop all configuration versions */
2117 STRV_FOREACH(p
, paths
.search_path
) {
2118 _cleanup_free_
char *path
= NULL
;
2121 path
= path_make_absolute(*i
, *p
);
2125 r
= lstat(path
, &st
);
2127 if (errno
!= ENOENT
)
2129 } else if (S_ISREG(st
.st_mode
) || S_ISLNK(st
.st_mode
)) {
2130 r
= path_is_config(&paths
, path
);
2134 if (!GREEDY_REALLOC0(todo
, n_allocated
, n_todo
+ 2))
2137 todo
[n_todo
++] = path
;
2147 STRV_FOREACH(i
, todo
) {
2148 _cleanup_strv_free_
char **fs
= NULL
;
2152 (void) get_files_in_directory(*i
, &fs
);
2154 q
= rm_rf(*i
, REMOVE_ROOT
|REMOVE_PHYSICAL
);
2155 if (q
< 0 && q
!= -ENOENT
&& r
>= 0) {
2160 STRV_FOREACH(j
, fs
) {
2161 _cleanup_free_
char *t
= NULL
;
2163 t
= strjoin(*i
, "/", *j
);
2167 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_UNLINK
, t
, NULL
);
2170 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_UNLINK
, *i
, NULL
);
2172 rp
= skip_root(&paths
, *i
);
2173 q
= mark_symlink_for_removal(&remove_symlinks_to
, rp
?: *i
);
2178 q
= remove_marked_symlinks(remove_symlinks_to
, paths
.runtime_config
, &paths
, false, changes
, n_changes
);
2182 q
= remove_marked_symlinks(remove_symlinks_to
, paths
.persistent_config
, &paths
, false, changes
, n_changes
);
2189 int unit_file_add_dependency(
2190 UnitFileScope scope
,
2191 UnitFileFlags flags
,
2192 const char *root_dir
,
2196 UnitFileChange
**changes
,
2197 unsigned *n_changes
) {
2199 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2200 _cleanup_(install_context_done
) InstallContext c
= {};
2201 UnitFileInstallInfo
*i
, *target_info
;
2202 const char *config_path
;
2207 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2210 if (!IN_SET(dep
, UNIT_WANTS
, UNIT_REQUIRES
))
2213 if (!unit_name_is_valid(target
, UNIT_NAME_ANY
))
2216 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2220 config_path
= (flags
& UNIT_FILE_RUNTIME
) ? paths
.runtime_config
: paths
.persistent_config
;
2222 r
= install_info_discover(scope
, &c
, &paths
, target
, SEARCH_FOLLOW_CONFIG_SYMLINKS
,
2223 &target_info
, changes
, n_changes
);
2226 r
= install_info_may_process(target_info
, &paths
, changes
, n_changes
);
2230 assert(target_info
->type
== UNIT_FILE_TYPE_REGULAR
);
2232 STRV_FOREACH(f
, files
) {
2235 r
= install_info_discover(scope
, &c
, &paths
, *f
, SEARCH_FOLLOW_CONFIG_SYMLINKS
,
2236 &i
, changes
, n_changes
);
2239 r
= install_info_may_process(i
, &paths
, changes
, n_changes
);
2243 assert(i
->type
== UNIT_FILE_TYPE_REGULAR
);
2245 /* We didn't actually load anything from the unit
2246 * file, but instead just add in our new symlink to
2249 if (dep
== UNIT_WANTS
)
2252 l
= &i
->required_by
;
2255 *l
= strv_new(target_info
->name
, NULL
);
2260 return install_context_apply(scope
, &c
, &paths
, config_path
, !!(flags
& UNIT_FILE_FORCE
), SEARCH_FOLLOW_CONFIG_SYMLINKS
, changes
, n_changes
);
2263 int unit_file_enable(
2264 UnitFileScope scope
,
2265 UnitFileFlags flags
,
2266 const char *root_dir
,
2268 UnitFileChange
**changes
,
2269 unsigned *n_changes
) {
2271 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2272 _cleanup_(install_context_done
) InstallContext c
= {};
2273 const char *config_path
;
2274 UnitFileInstallInfo
*i
;
2279 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2281 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2285 config_path
= (flags
& UNIT_FILE_RUNTIME
) ? paths
.runtime_config
: paths
.persistent_config
;
2287 STRV_FOREACH(f
, files
) {
2288 r
= install_info_discover(scope
, &c
, &paths
, *f
, SEARCH_LOAD
|SEARCH_FOLLOW_CONFIG_SYMLINKS
,
2289 &i
, changes
, n_changes
);
2292 r
= install_info_may_process(i
, &paths
, changes
, n_changes
);
2296 assert(i
->type
== UNIT_FILE_TYPE_REGULAR
);
2299 /* This will return the number of symlink rules that were
2300 supposed to be created, not the ones actually created. This
2301 is useful to determine whether the passed files had any
2302 installation data at all. */
2304 return install_context_apply(scope
, &c
, &paths
, config_path
, !!(flags
& UNIT_FILE_FORCE
), SEARCH_LOAD
, changes
, n_changes
);
2307 int unit_file_disable(
2308 UnitFileScope scope
,
2309 UnitFileFlags flags
,
2310 const char *root_dir
,
2312 UnitFileChange
**changes
,
2313 unsigned *n_changes
) {
2315 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2316 _cleanup_(install_context_done
) InstallContext c
= {};
2317 _cleanup_set_free_free_ Set
*remove_symlinks_to
= NULL
;
2318 const char *config_path
;
2323 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2325 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2329 config_path
= (flags
& UNIT_FILE_RUNTIME
) ? paths
.runtime_config
: paths
.persistent_config
;
2331 STRV_FOREACH(i
, files
) {
2332 if (!unit_name_is_valid(*i
, UNIT_NAME_ANY
))
2335 r
= install_info_add(&c
, *i
, NULL
, false, NULL
);
2340 r
= install_context_mark_for_removal(scope
, &c
, &paths
, &remove_symlinks_to
, config_path
);
2344 return remove_marked_symlinks(remove_symlinks_to
, config_path
, &paths
, !!(flags
& UNIT_FILE_DRY_RUN
), changes
, n_changes
);
2347 int unit_file_reenable(
2348 UnitFileScope scope
,
2349 UnitFileFlags flags
,
2350 const char *root_dir
,
2352 UnitFileChange
**changes
,
2353 unsigned *n_changes
) {
2359 /* First, we invoke the disable command with only the basename... */
2360 l
= strv_length(files
);
2361 n
= newa(char*, l
+1);
2362 for (i
= 0; i
< l
; i
++)
2363 n
[i
] = basename(files
[i
]);
2366 r
= unit_file_disable(scope
, flags
, root_dir
, n
, changes
, n_changes
);
2370 /* But the enable command with the full name */
2371 return unit_file_enable(scope
, flags
, root_dir
, files
, changes
, n_changes
);
2374 int unit_file_set_default(
2375 UnitFileScope scope
,
2376 UnitFileFlags flags
,
2377 const char *root_dir
,
2379 UnitFileChange
**changes
,
2380 unsigned *n_changes
) {
2382 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2383 _cleanup_(install_context_done
) InstallContext c
= {};
2384 UnitFileInstallInfo
*i
;
2385 const char *new_path
;
2389 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2392 if (unit_name_to_type(name
) != UNIT_TARGET
) /* this also validates the name */
2394 if (streq(name
, SPECIAL_DEFAULT_TARGET
))
2397 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2401 r
= install_info_discover(scope
, &c
, &paths
, name
, 0, &i
, changes
, n_changes
);
2404 r
= install_info_may_process(i
, &paths
, changes
, n_changes
);
2408 new_path
= strjoina(paths
.persistent_config
, "/" SPECIAL_DEFAULT_TARGET
);
2409 return create_symlink(&paths
, i
->path
, new_path
, !!(flags
& UNIT_FILE_FORCE
), changes
, n_changes
);
2412 int unit_file_get_default(
2413 UnitFileScope scope
,
2414 const char *root_dir
,
2417 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2418 _cleanup_(install_context_done
) InstallContext c
= {};
2419 UnitFileInstallInfo
*i
;
2424 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2427 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2431 r
= install_info_discover(scope
, &c
, &paths
, SPECIAL_DEFAULT_TARGET
, SEARCH_FOLLOW_CONFIG_SYMLINKS
,
2435 r
= install_info_may_process(i
, &paths
, NULL
, 0);
2439 n
= strdup(i
->name
);
2447 static int unit_file_lookup_state(
2448 UnitFileScope scope
,
2449 const LookupPaths
*paths
,
2451 UnitFileState
*ret
) {
2453 _cleanup_(install_context_done
) InstallContext c
= {};
2454 UnitFileInstallInfo
*i
;
2455 UnitFileState state
;
2461 if (!unit_name_is_valid(name
, UNIT_NAME_ANY
))
2464 r
= install_info_discover(scope
, &c
, paths
, name
, SEARCH_LOAD
|SEARCH_FOLLOW_CONFIG_SYMLINKS
,
2469 /* Shortcut things, if the caller just wants to know if this unit exists. */
2475 case UNIT_FILE_TYPE_MASKED
:
2476 r
= path_is_runtime(paths
, i
->path
);
2480 state
= r
> 0 ? UNIT_FILE_MASKED_RUNTIME
: UNIT_FILE_MASKED
;
2483 case UNIT_FILE_TYPE_REGULAR
:
2484 r
= path_is_generator(paths
, i
->path
);
2488 state
= UNIT_FILE_GENERATED
;
2492 r
= path_is_transient(paths
, i
->path
);
2496 state
= UNIT_FILE_TRANSIENT
;
2500 r
= find_symlinks_in_scope(scope
, paths
, i
->name
, &state
);
2504 if (UNIT_FILE_INSTALL_INFO_HAS_RULES(i
))
2505 state
= UNIT_FILE_DISABLED
;
2506 else if (UNIT_FILE_INSTALL_INFO_HAS_ALSO(i
))
2507 state
= UNIT_FILE_INDIRECT
;
2509 state
= UNIT_FILE_STATIC
;
2515 assert_not_reached("Unexpect unit file type.");
2522 int unit_file_get_state(
2523 UnitFileScope scope
,
2524 const char *root_dir
,
2526 UnitFileState
*ret
) {
2528 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2532 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2535 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2539 return unit_file_lookup_state(scope
, &paths
, name
, ret
);
2542 int unit_file_exists(UnitFileScope scope
, const LookupPaths
*paths
, const char *name
) {
2543 _cleanup_(install_context_done
) InstallContext c
= {};
2549 if (!unit_name_is_valid(name
, UNIT_NAME_ANY
))
2552 r
= install_info_discover(scope
, &c
, paths
, name
, 0, NULL
, NULL
, NULL
);
2561 static int read_presets(UnitFileScope scope
, const char *root_dir
, Presets
*presets
) {
2562 _cleanup_(presets_freep
) Presets ps
= {};
2563 size_t n_allocated
= 0;
2564 _cleanup_strv_free_
char **files
= NULL
;
2569 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2572 if (scope
== UNIT_FILE_SYSTEM
)
2573 r
= conf_files_list(&files
, ".preset", root_dir
,
2574 "/etc/systemd/system-preset",
2575 "/usr/local/lib/systemd/system-preset",
2576 "/usr/lib/systemd/system-preset",
2577 #ifdef HAVE_SPLIT_USR
2578 "/lib/systemd/system-preset",
2581 else if (scope
== UNIT_FILE_GLOBAL
)
2582 r
= conf_files_list(&files
, ".preset", root_dir
,
2583 "/etc/systemd/user-preset",
2584 "/usr/local/lib/systemd/user-preset",
2585 "/usr/lib/systemd/user-preset",
2588 *presets
= (Presets
){};
2596 STRV_FOREACH(p
, files
) {
2597 _cleanup_fclose_
FILE *f
;
2598 char line
[LINE_MAX
];
2601 f
= fopen(*p
, "re");
2603 if (errno
== ENOENT
)
2609 FOREACH_LINE(line
, f
, return -errno
) {
2610 PresetRule rule
= {};
2611 const char *parameter
;
2619 if (strchr(COMMENTS
, *l
))
2622 parameter
= first_word(l
, "enable");
2626 pattern
= strdup(parameter
);
2630 rule
= (PresetRule
) {
2632 .action
= PRESET_ENABLE
,
2636 parameter
= first_word(l
, "disable");
2640 pattern
= strdup(parameter
);
2644 rule
= (PresetRule
) {
2646 .action
= PRESET_DISABLE
,
2651 if (!GREEDY_REALLOC(ps
.rules
, n_allocated
, ps
.n_rules
+ 1))
2654 ps
.rules
[ps
.n_rules
++] = rule
;
2658 log_syntax(NULL
, LOG_WARNING
, *p
, n
, 0, "Couldn't parse line '%s'. Ignoring.", line
);
2668 static int query_presets(const char *name
, const Presets presets
) {
2669 PresetAction action
= PRESET_UNKNOWN
;
2672 if (!unit_name_is_valid(name
, UNIT_NAME_ANY
))
2675 for (i
= 0; i
< presets
.n_rules
; i
++)
2676 if (fnmatch(presets
.rules
[i
].pattern
, name
, FNM_NOESCAPE
) == 0) {
2677 action
= presets
.rules
[i
].action
;
2682 case PRESET_UNKNOWN
:
2683 log_debug("Preset files don't specify rule for %s. Enabling.", name
);
2686 log_debug("Preset files say enable %s.", name
);
2688 case PRESET_DISABLE
:
2689 log_debug("Preset files say disable %s.", name
);
2692 assert_not_reached("invalid preset action");
2696 int unit_file_query_preset(UnitFileScope scope
, const char *root_dir
, const char *name
) {
2697 _cleanup_(presets_freep
) Presets presets
= {};
2700 r
= read_presets(scope
, root_dir
, &presets
);
2704 return query_presets(name
, presets
);
2707 static int execute_preset(
2708 UnitFileScope scope
,
2709 InstallContext
*plus
,
2710 InstallContext
*minus
,
2711 const LookupPaths
*paths
,
2712 const char *config_path
,
2714 UnitFilePresetMode mode
,
2716 UnitFileChange
**changes
,
2717 unsigned *n_changes
) {
2724 assert(config_path
);
2726 if (mode
!= UNIT_FILE_PRESET_ENABLE_ONLY
) {
2727 _cleanup_set_free_free_ Set
*remove_symlinks_to
= NULL
;
2729 r
= install_context_mark_for_removal(scope
, minus
, paths
, &remove_symlinks_to
, config_path
);
2733 r
= remove_marked_symlinks(remove_symlinks_to
, config_path
, paths
, false, changes
, n_changes
);
2737 if (mode
!= UNIT_FILE_PRESET_DISABLE_ONLY
) {
2740 /* Returns number of symlinks that where supposed to be installed. */
2741 q
= install_context_apply(scope
, plus
, paths
, config_path
, force
, SEARCH_LOAD
, changes
, n_changes
);
2753 static int preset_prepare_one(
2754 UnitFileScope scope
,
2755 InstallContext
*plus
,
2756 InstallContext
*minus
,
2760 UnitFileChange
**changes
,
2761 unsigned *n_changes
) {
2763 _cleanup_(install_context_done
) InstallContext tmp
= {};
2764 UnitFileInstallInfo
*i
;
2767 if (install_info_find(plus
, name
) || install_info_find(minus
, name
))
2770 r
= install_info_discover(scope
, &tmp
, paths
, name
, SEARCH_FOLLOW_CONFIG_SYMLINKS
,
2771 &i
, changes
, n_changes
);
2774 if (!streq(name
, i
->name
)) {
2775 log_debug("Skipping %s because is an alias for %s", name
, i
->name
);
2779 r
= query_presets(name
, presets
);
2784 r
= install_info_discover(scope
, plus
, paths
, name
, SEARCH_LOAD
|SEARCH_FOLLOW_CONFIG_SYMLINKS
,
2785 &i
, changes
, n_changes
);
2789 r
= install_info_may_process(i
, paths
, changes
, n_changes
);
2793 r
= install_info_discover(scope
, minus
, paths
, name
, SEARCH_FOLLOW_CONFIG_SYMLINKS
,
2794 &i
, changes
, n_changes
);
2799 int unit_file_preset(
2800 UnitFileScope scope
,
2801 UnitFileFlags flags
,
2802 const char *root_dir
,
2804 UnitFilePresetMode mode
,
2805 UnitFileChange
**changes
,
2806 unsigned *n_changes
) {
2808 _cleanup_(install_context_done
) InstallContext plus
= {}, minus
= {};
2809 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2810 _cleanup_(presets_freep
) Presets presets
= {};
2811 const char *config_path
;
2816 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2817 assert(mode
< _UNIT_FILE_PRESET_MAX
);
2819 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2823 config_path
= (flags
& UNIT_FILE_RUNTIME
) ? paths
.runtime_config
: paths
.persistent_config
;
2825 r
= read_presets(scope
, root_dir
, &presets
);
2829 STRV_FOREACH(i
, files
) {
2830 r
= preset_prepare_one(scope
, &plus
, &minus
, &paths
, *i
, presets
, changes
, n_changes
);
2835 return execute_preset(scope
, &plus
, &minus
, &paths
, config_path
, files
, mode
, !!(flags
& UNIT_FILE_FORCE
), changes
, n_changes
);
2838 int unit_file_preset_all(
2839 UnitFileScope scope
,
2840 UnitFileFlags flags
,
2841 const char *root_dir
,
2842 UnitFilePresetMode mode
,
2843 UnitFileChange
**changes
,
2844 unsigned *n_changes
) {
2846 _cleanup_(install_context_done
) InstallContext plus
= {}, minus
= {};
2847 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2848 _cleanup_(presets_freep
) Presets presets
= {};
2849 const char *config_path
= NULL
;
2854 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2855 assert(mode
< _UNIT_FILE_PRESET_MAX
);
2857 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2861 config_path
= (flags
& UNIT_FILE_RUNTIME
) ? paths
.runtime_config
: paths
.persistent_config
;
2863 r
= read_presets(scope
, root_dir
, &presets
);
2867 STRV_FOREACH(i
, paths
.search_path
) {
2868 _cleanup_closedir_
DIR *d
= NULL
;
2873 if (errno
== ENOENT
)
2879 FOREACH_DIRENT(de
, d
, return -errno
) {
2881 if (!unit_name_is_valid(de
->d_name
, UNIT_NAME_ANY
))
2884 dirent_ensure_type(d
, de
);
2886 if (!IN_SET(de
->d_type
, DT_LNK
, DT_REG
))
2889 /* we don't pass changes[] in, because we want to handle errors on our own */
2890 r
= preset_prepare_one(scope
, &plus
, &minus
, &paths
, de
->d_name
, presets
, NULL
, 0);
2892 r
= unit_file_changes_add(changes
, n_changes
,
2893 UNIT_FILE_IS_MASKED
, de
->d_name
, NULL
);
2894 else if (r
== -ENOLINK
)
2895 r
= unit_file_changes_add(changes
, n_changes
,
2896 UNIT_FILE_IS_DANGLING
, de
->d_name
, NULL
);
2902 return execute_preset(scope
, &plus
, &minus
, &paths
, config_path
, NULL
, mode
, !!(flags
& UNIT_FILE_FORCE
), changes
, n_changes
);
2905 static void unit_file_list_free_one(UnitFileList
*f
) {
2913 Hashmap
* unit_file_list_free(Hashmap
*h
) {
2916 while ((i
= hashmap_steal_first(h
)))
2917 unit_file_list_free_one(i
);
2919 return hashmap_free(h
);
2922 DEFINE_TRIVIAL_CLEANUP_FUNC(UnitFileList
*, unit_file_list_free_one
);
2924 int unit_file_get_list(
2925 UnitFileScope scope
,
2926 const char *root_dir
,
2931 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2936 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2939 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2943 STRV_FOREACH(i
, paths
.search_path
) {
2944 _cleanup_closedir_
DIR *d
= NULL
;
2949 if (errno
== ENOENT
)
2951 if (IN_SET(errno
, ENOTDIR
, EACCES
)) {
2952 log_debug("Failed to open \"%s\": %m", *i
);
2959 FOREACH_DIRENT(de
, d
, return -errno
) {
2960 _cleanup_(unit_file_list_free_onep
) UnitFileList
*f
= NULL
;
2962 if (!unit_name_is_valid(de
->d_name
, UNIT_NAME_ANY
))
2965 if (!strv_fnmatch_or_empty(patterns
, de
->d_name
, FNM_NOESCAPE
))
2968 if (hashmap_get(h
, de
->d_name
))
2971 dirent_ensure_type(d
, de
);
2973 if (!IN_SET(de
->d_type
, DT_LNK
, DT_REG
))
2976 f
= new0(UnitFileList
, 1);
2980 f
->path
= path_make_absolute(de
->d_name
, *i
);
2984 r
= unit_file_lookup_state(scope
, &paths
, de
->d_name
, &f
->state
);
2986 f
->state
= UNIT_FILE_BAD
;
2988 if (!strv_isempty(states
) &&
2989 !strv_contains(states
, unit_file_state_to_string(f
->state
)))
2992 r
= hashmap_put(h
, basename(f
->path
), f
);
2996 f
= NULL
; /* prevent cleanup */
3003 static const char* const unit_file_state_table
[_UNIT_FILE_STATE_MAX
] = {
3004 [UNIT_FILE_ENABLED
] = "enabled",
3005 [UNIT_FILE_ENABLED_RUNTIME
] = "enabled-runtime",
3006 [UNIT_FILE_LINKED
] = "linked",
3007 [UNIT_FILE_LINKED_RUNTIME
] = "linked-runtime",
3008 [UNIT_FILE_MASKED
] = "masked",
3009 [UNIT_FILE_MASKED_RUNTIME
] = "masked-runtime",
3010 [UNIT_FILE_STATIC
] = "static",
3011 [UNIT_FILE_DISABLED
] = "disabled",
3012 [UNIT_FILE_INDIRECT
] = "indirect",
3013 [UNIT_FILE_GENERATED
] = "generated",
3014 [UNIT_FILE_TRANSIENT
] = "transient",
3015 [UNIT_FILE_BAD
] = "bad",
3018 DEFINE_STRING_TABLE_LOOKUP(unit_file_state
, UnitFileState
);
3020 static const char* const unit_file_change_type_table
[_UNIT_FILE_CHANGE_TYPE_MAX
] = {
3021 [UNIT_FILE_SYMLINK
] = "symlink",
3022 [UNIT_FILE_UNLINK
] = "unlink",
3023 [UNIT_FILE_IS_MASKED
] = "masked",
3024 [UNIT_FILE_IS_DANGLING
] = "dangling",
3027 DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type
, UnitFileChangeType
);
3029 static const char* const unit_file_preset_mode_table
[_UNIT_FILE_PRESET_MAX
] = {
3030 [UNIT_FILE_PRESET_FULL
] = "full",
3031 [UNIT_FILE_PRESET_ENABLE_ONLY
] = "enable-only",
3032 [UNIT_FILE_PRESET_DISABLE_ONLY
] = "disable-only",
3035 DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode
, UnitFilePresetMode
);