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
, bool check_parent
) {
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 */
221 parent
= dirname_malloc(path
);
228 return path_equal_ptr(path
, p
->persistent_config
) ||
229 path_equal_ptr(path
, p
->runtime_config
);
232 static int path_is_runtime(const LookupPaths
*p
, const char *path
, bool check_parent
) {
233 _cleanup_free_
char *parent
= NULL
;
239 /* Everything in /run is considered runtime. On top of that we also add
240 * explicit checks for the various runtime directories, as safety net. */
242 rpath
= skip_root(p
, path
);
243 if (rpath
&& path_startswith(rpath
, "/run"))
247 parent
= dirname_malloc(path
);
254 return path_equal_ptr(path
, p
->runtime_config
) ||
255 path_equal_ptr(path
, p
->generator
) ||
256 path_equal_ptr(path
, p
->generator_early
) ||
257 path_equal_ptr(path
, p
->generator_late
) ||
258 path_equal_ptr(path
, p
->transient
) ||
259 path_equal_ptr(path
, p
->runtime_control
);
262 static int path_is_vendor(const LookupPaths
*p
, const char *path
) {
268 rpath
= skip_root(p
, path
);
272 if (path_startswith(rpath
, "/usr"))
275 #ifdef HAVE_SPLIT_USR
276 if (path_startswith(rpath
, "/lib"))
280 return path_equal(rpath
, SYSTEM_DATA_UNIT_PATH
);
283 int unit_file_changes_add(
284 UnitFileChange
**changes
,
286 UnitFileChangeType type
,
288 const char *source
) {
290 _cleanup_free_
char *p
= NULL
, *s
= NULL
;
294 assert(!changes
== !n_changes
);
299 c
= realloc(*changes
, (*n_changes
+ 1) * sizeof(UnitFileChange
));
308 if (!p
|| (source
&& !s
))
311 path_kill_slashes(p
);
313 path_kill_slashes(s
);
315 c
[*n_changes
] = (UnitFileChange
) { type
, p
, s
};
321 void unit_file_changes_free(UnitFileChange
*changes
, unsigned n_changes
) {
324 assert(changes
|| n_changes
== 0);
326 for (i
= 0; i
< n_changes
; i
++) {
327 free(changes
[i
].path
);
328 free(changes
[i
].source
);
334 void unit_file_dump_changes(int r
, const char *verb
, const UnitFileChange
*changes
, unsigned n_changes
, bool quiet
) {
338 assert(changes
|| n_changes
== 0);
339 /* If verb is not specified, errors are not allowed! */
340 assert(verb
|| r
>= 0);
342 for (i
= 0; i
< n_changes
; i
++) {
343 assert(verb
|| changes
[i
].type
>= 0);
345 switch(changes
[i
].type
) {
346 case UNIT_FILE_SYMLINK
:
348 log_info("Created symlink %s %s %s.",
350 special_glyph(ARROW
),
353 case UNIT_FILE_UNLINK
:
355 log_info("Removed %s.", changes
[i
].path
);
357 case UNIT_FILE_IS_MASKED
:
359 log_info("Unit %s is masked, ignoring.", changes
[i
].path
);
361 case UNIT_FILE_IS_DANGLING
:
363 log_info("Unit %s is an alias to a unit that is not present, ignoring.",
367 if (changes
[i
].source
)
368 log_error_errno(changes
[i
].type
,
369 "Failed to %s unit, file %s already exists and is a symlink to %s.",
370 verb
, changes
[i
].path
, changes
[i
].source
);
372 log_error_errno(changes
[i
].type
,
373 "Failed to %s unit, file %s already exists.",
374 verb
, changes
[i
].path
);
378 log_error_errno(changes
[i
].type
, "Failed to %s unit, unit %s is masked.",
379 verb
, changes
[i
].path
);
383 log_error_errno(changes
[i
].type
, "Failed to %s unit, unit %s is transient or generated.",
384 verb
, changes
[i
].path
);
388 log_error_errno(changes
[i
].type
, "Failed to %s unit, refusing to operate on linked unit file %s",
389 verb
, changes
[i
].path
);
394 log_error_errno(changes
[i
].type
, "Failed to %s unit, unit %s does not exist.", verb
, changes
[i
].path
);
399 assert(changes
[i
].type
< 0);
400 log_error_errno(changes
[i
].type
, "Failed to %s unit, file %s: %m.",
401 verb
, changes
[i
].path
);
406 if (r
< 0 && !logged
)
407 log_error_errno(r
, "Failed to %s: %m.", verb
);
411 * Checks if two paths or symlinks from wd are the same, when root is the root of the filesystem.
412 * wc should be the full path in the host file system.
414 static bool chroot_symlinks_same(const char *root
, const char *wd
, const char *a
, const char *b
) {
415 assert(path_is_absolute(wd
));
417 /* This will give incorrect results if the paths are relative and go outside
418 * of the chroot. False negatives are possible. */
423 a
= strjoina(path_is_absolute(a
) ? root
: wd
, "/", a
);
424 b
= strjoina(path_is_absolute(b
) ? root
: wd
, "/", b
);
425 return path_equal_or_files_same(a
, b
, 0);
428 static int create_symlink(
429 const LookupPaths
*paths
,
430 const char *old_path
,
431 const char *new_path
,
433 UnitFileChange
**changes
,
434 unsigned *n_changes
) {
436 _cleanup_free_
char *dest
= NULL
, *dirname
= NULL
;
443 rp
= skip_root(paths
, old_path
);
447 /* Actually create a symlink, and remember that we did. Is
448 * smart enough to check if there's already a valid symlink in
451 * Returns 1 if a symlink was created or already exists and points to
452 * the right place, or negative on error.
455 mkdir_parents_label(new_path
, 0755);
457 if (symlink(old_path
, new_path
) >= 0) {
458 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_SYMLINK
, new_path
, old_path
);
462 if (errno
!= EEXIST
) {
463 unit_file_changes_add(changes
, n_changes
, -errno
, new_path
, NULL
);
467 r
= readlink_malloc(new_path
, &dest
);
469 /* translate EINVAL (non-symlink exists) to EEXIST */
473 unit_file_changes_add(changes
, n_changes
, r
, new_path
, NULL
);
477 dirname
= dirname_malloc(new_path
);
481 if (chroot_symlinks_same(paths
->root_dir
, dirname
, dest
, old_path
))
485 unit_file_changes_add(changes
, n_changes
, -EEXIST
, new_path
, dest
);
489 r
= symlink_atomic(old_path
, new_path
);
491 unit_file_changes_add(changes
, n_changes
, r
, new_path
, NULL
);
495 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_UNLINK
, new_path
, NULL
);
496 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_SYMLINK
, new_path
, old_path
);
501 static int mark_symlink_for_removal(
502 Set
**remove_symlinks_to
,
510 r
= set_ensure_allocated(remove_symlinks_to
, &string_hash_ops
);
518 path_kill_slashes(n
);
520 r
= set_consume(*remove_symlinks_to
, n
);
529 static int remove_marked_symlinks_fd(
530 Set
*remove_symlinks_to
,
533 const char *config_path
,
534 const LookupPaths
*lp
,
537 UnitFileChange
**changes
,
538 unsigned *n_changes
) {
540 _cleanup_closedir_
DIR *d
= NULL
;
544 assert(remove_symlinks_to
);
559 FOREACH_DIRENT(de
, d
, return -errno
) {
561 dirent_ensure_type(d
, de
);
563 if (de
->d_type
== DT_DIR
) {
564 _cleanup_free_
char *p
= NULL
;
567 nfd
= openat(fd
, de
->d_name
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
|O_NOFOLLOW
);
577 p
= path_make_absolute(de
->d_name
, path
);
583 /* This will close nfd, regardless whether it succeeds or not */
584 q
= remove_marked_symlinks_fd(remove_symlinks_to
, nfd
, p
, config_path
, lp
, dry_run
, restart
, changes
, n_changes
);
588 } else if (de
->d_type
== DT_LNK
) {
589 _cleanup_free_
char *p
= NULL
, *dest
= NULL
;
594 if (!unit_name_is_valid(de
->d_name
, UNIT_NAME_ANY
))
597 p
= path_make_absolute(de
->d_name
, path
);
600 path_kill_slashes(p
);
602 q
= readlink_malloc(p
, &dest
);
611 /* We remove all links pointing to a file or path that is marked, as well as all files sharing
612 * the same name as a file that is marked. */
614 found
= set_contains(remove_symlinks_to
, dest
) ||
615 set_contains(remove_symlinks_to
, basename(dest
)) ||
616 set_contains(remove_symlinks_to
, de
->d_name
);
622 if (unlinkat(fd
, de
->d_name
, 0) < 0 && errno
!= ENOENT
) {
625 unit_file_changes_add(changes
, n_changes
, -errno
, p
, NULL
);
629 (void) rmdir_parents(p
, config_path
);
632 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_UNLINK
, p
, NULL
);
634 /* Now, remember the full path (but with the root prefix removed) of
635 * the symlink we just removed, and remove any symlinks to it, too. */
637 rp
= skip_root(lp
, p
);
638 q
= mark_symlink_for_removal(&remove_symlinks_to
, rp
?: p
);
641 if (q
> 0 && !dry_run
)
649 static int remove_marked_symlinks(
650 Set
*remove_symlinks_to
,
651 const char *config_path
,
652 const LookupPaths
*lp
,
654 UnitFileChange
**changes
,
655 unsigned *n_changes
) {
657 _cleanup_close_
int fd
= -1;
664 if (set_size(remove_symlinks_to
) <= 0)
667 fd
= open(config_path
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
);
669 return errno
== ENOENT
? 0 : -errno
;
675 cfd
= fcntl(fd
, F_DUPFD_CLOEXEC
, 3);
679 /* This takes possession of cfd and closes it */
680 q
= remove_marked_symlinks_fd(remove_symlinks_to
, cfd
, config_path
, config_path
, lp
, dry_run
, &restart
, changes
, n_changes
);
688 static int find_symlinks_fd(
689 const char *root_dir
,
693 const char *config_path
,
694 bool *same_name_link
) {
696 _cleanup_closedir_
DIR *d
= NULL
;
704 assert(same_name_link
);
712 FOREACH_DIRENT(de
, d
, return -errno
) {
714 dirent_ensure_type(d
, de
);
716 if (de
->d_type
== DT_DIR
) {
717 _cleanup_free_
char *p
= NULL
;
720 nfd
= openat(fd
, de
->d_name
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
|O_NOFOLLOW
);
730 p
= path_make_absolute(de
->d_name
, path
);
736 /* This will close nfd, regardless whether it succeeds or not */
737 q
= find_symlinks_fd(root_dir
, name
, nfd
, p
, config_path
, same_name_link
);
743 } else if (de
->d_type
== DT_LNK
) {
744 _cleanup_free_
char *p
= NULL
, *dest
= NULL
;
745 bool found_path
, found_dest
, b
= false;
748 /* Acquire symlink name */
749 p
= path_make_absolute(de
->d_name
, path
);
753 /* Acquire symlink destination */
754 q
= readlink_malloc(p
, &dest
);
764 if (!path_is_absolute(dest
)) {
767 x
= prefix_root(root_dir
, dest
);
775 /* Check if the symlink itself matches what we
777 if (path_is_absolute(name
))
778 found_path
= path_equal(p
, name
);
780 found_path
= streq(de
->d_name
, name
);
782 /* Check if what the symlink points to
783 * matches what we are looking for */
784 if (path_is_absolute(name
))
785 found_dest
= path_equal(dest
, name
);
787 found_dest
= streq(basename(dest
), name
);
789 if (found_path
&& found_dest
) {
790 _cleanup_free_
char *t
= NULL
;
792 /* Filter out same name links in the main
794 t
= path_make_absolute(name
, config_path
);
798 b
= path_equal(t
, p
);
802 *same_name_link
= true;
803 else if (found_path
|| found_dest
)
811 static int find_symlinks(
812 const char *root_dir
,
814 const char *config_path
,
815 bool *same_name_link
) {
821 assert(same_name_link
);
823 fd
= open(config_path
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
);
825 if (IN_SET(errno
, ENOENT
, ENOTDIR
, EACCES
))
830 /* This takes possession of fd and closes it */
831 return find_symlinks_fd(root_dir
, name
, fd
, config_path
, config_path
, same_name_link
);
834 static int find_symlinks_in_scope(
835 const LookupPaths
*paths
,
837 UnitFileState
*state
) {
839 bool same_name_link_runtime
= false, same_name_link_config
= false;
840 bool enabled_in_runtime
= false, enabled_at_all
= false;
847 STRV_FOREACH(p
, paths
->search_path
) {
848 bool same_name_link
= false;
850 r
= find_symlinks(paths
->root_dir
, name
, *p
, &same_name_link
);
854 /* We found symlinks in this dir? Yay! Let's see where precisely it is enabled. */
856 r
= path_is_config(paths
, *p
, false);
860 /* This is the best outcome, let's return it immediately. */
861 *state
= UNIT_FILE_ENABLED
;
865 r
= path_is_runtime(paths
, *p
, false);
869 enabled_in_runtime
= true;
871 enabled_at_all
= true;
873 } else if (same_name_link
) {
875 r
= path_is_config(paths
, *p
, false);
879 same_name_link_config
= true;
881 r
= path_is_runtime(paths
, *p
, false);
885 same_name_link_runtime
= true;
890 if (enabled_in_runtime
) {
891 *state
= UNIT_FILE_ENABLED_RUNTIME
;
895 /* Here's a special rule: if the unit we are looking for is an instance, and it symlinked in the search path
896 * outside of runtime and configuration directory, then we consider it statically enabled. Note we do that only
897 * for instance, not for regular names, as those are merely aliases, while instances explicitly instantiate
898 * something, and hence are a much stronger concept. */
899 if (enabled_at_all
&& unit_name_is_valid(name
, UNIT_NAME_INSTANCE
)) {
900 *state
= UNIT_FILE_STATIC
;
904 /* Hmm, we didn't find it, but maybe we found the same name
906 if (same_name_link_config
) {
907 *state
= UNIT_FILE_LINKED
;
910 if (same_name_link_runtime
) {
911 *state
= UNIT_FILE_LINKED_RUNTIME
;
918 static void install_info_free(UnitFileInstallInfo
*i
) {
925 strv_free(i
->aliases
);
926 strv_free(i
->wanted_by
);
927 strv_free(i
->required_by
);
929 free(i
->default_instance
);
930 free(i
->symlink_target
);
934 static OrderedHashmap
* install_info_hashmap_free(OrderedHashmap
*m
) {
935 UnitFileInstallInfo
*i
;
940 while ((i
= ordered_hashmap_steal_first(m
)))
941 install_info_free(i
);
943 return ordered_hashmap_free(m
);
946 static void install_context_done(InstallContext
*c
) {
949 c
->will_process
= install_info_hashmap_free(c
->will_process
);
950 c
->have_processed
= install_info_hashmap_free(c
->have_processed
);
953 static UnitFileInstallInfo
*install_info_find(InstallContext
*c
, const char *name
) {
954 UnitFileInstallInfo
*i
;
956 i
= ordered_hashmap_get(c
->have_processed
, name
);
960 return ordered_hashmap_get(c
->will_process
, name
);
963 static int install_info_may_process(
964 UnitFileInstallInfo
*i
,
965 const LookupPaths
*paths
,
966 UnitFileChange
**changes
,
967 unsigned *n_changes
) {
971 /* Checks whether the loaded unit file is one we should process, or is masked,
972 * transient or generated and thus not subject to enable/disable operations. */
974 if (i
->type
== UNIT_FILE_TYPE_MASKED
) {
975 unit_file_changes_add(changes
, n_changes
, -ERFKILL
, i
->path
, NULL
);
978 if (path_is_generator(paths
, i
->path
) ||
979 path_is_transient(paths
, i
->path
)) {
980 unit_file_changes_add(changes
, n_changes
, -EADDRNOTAVAIL
, i
->path
, NULL
);
981 return -EADDRNOTAVAIL
;
988 * Adds a new UnitFileInstallInfo entry under name in the InstallContext.will_process
989 * hashmap, or retrieves the existing one if already present.
991 * Returns negative on error, 0 if the unit was already known, 1 otherwise.
993 static int install_info_add(
998 UnitFileInstallInfo
**ret
) {
1000 UnitFileInstallInfo
*i
= NULL
;
1004 assert(name
|| path
);
1007 name
= basename(path
);
1009 if (!unit_name_is_valid(name
, UNIT_NAME_ANY
))
1012 i
= install_info_find(c
, name
);
1014 i
->auxiliary
= i
->auxiliary
&& auxiliary
;
1021 r
= ordered_hashmap_ensure_allocated(&c
->will_process
, &string_hash_ops
);
1025 i
= new0(UnitFileInstallInfo
, 1);
1028 i
->type
= _UNIT_FILE_TYPE_INVALID
;
1029 i
->auxiliary
= auxiliary
;
1031 i
->name
= strdup(name
);
1038 i
->path
= strdup(path
);
1045 r
= ordered_hashmap_put(c
->will_process
, i
->name
, i
);
1055 install_info_free(i
);
1059 static int config_parse_alias(
1061 const char *filename
,
1063 const char *section
,
1064 unsigned section_line
,
1078 name
= basename(filename
);
1079 type
= unit_name_to_type(name
);
1080 if (!unit_type_may_alias(type
))
1081 return log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1082 "Alias= is not allowed for %s units, ignoring.",
1083 unit_type_to_string(type
));
1085 return config_parse_strv(unit
, filename
, line
, section
, section_line
,
1086 lvalue
, ltype
, rvalue
, data
, userdata
);
1089 static int config_parse_also(
1091 const char *filename
,
1093 const char *section
,
1094 unsigned section_line
,
1101 UnitFileInstallInfo
*info
= userdata
, *alsoinfo
= NULL
;
1102 InstallContext
*c
= data
;
1110 _cleanup_free_
char *word
= NULL
, *printed
= NULL
;
1112 r
= extract_first_word(&rvalue
, &word
, NULL
, 0);
1118 r
= install_full_printf(info
, word
, &printed
);
1122 if (!unit_name_is_valid(printed
, UNIT_NAME_ANY
))
1125 r
= install_info_add(c
, printed
, NULL
, true, &alsoinfo
);
1129 r
= strv_push(&info
->also
, printed
);
1139 static int config_parse_default_instance(
1141 const char *filename
,
1143 const char *section
,
1144 unsigned section_line
,
1151 UnitFileInstallInfo
*i
= data
;
1153 _cleanup_free_
char *printed
= NULL
;
1160 name
= basename(filename
);
1161 if (unit_name_is_valid(name
, UNIT_NAME_INSTANCE
))
1162 /* When enabling an instance, we might be using a template unit file,
1163 * but we should ignore DefaultInstance silently. */
1165 if (!unit_name_is_valid(name
, UNIT_NAME_TEMPLATE
))
1166 return log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1167 "DefaultInstance= only makes sense for template units, ignoring.");
1169 r
= install_full_printf(i
, rvalue
, &printed
);
1173 if (!unit_instance_is_valid(printed
))
1176 return free_and_replace(i
->default_instance
, printed
);
1179 static int unit_file_load(
1181 UnitFileInstallInfo
*info
,
1183 SearchFlags flags
) {
1185 const ConfigTableItem items
[] = {
1186 { "Install", "Alias", config_parse_alias
, 0, &info
->aliases
},
1187 { "Install", "WantedBy", config_parse_strv
, 0, &info
->wanted_by
},
1188 { "Install", "RequiredBy", config_parse_strv
, 0, &info
->required_by
},
1189 { "Install", "DefaultInstance", config_parse_default_instance
, 0, info
},
1190 { "Install", "Also", config_parse_also
, 0, c
},
1196 _cleanup_fclose_
FILE *f
= NULL
;
1197 _cleanup_close_
int fd
= -1;
1204 name
= basename(path
);
1205 type
= unit_name_to_type(name
);
1206 if (unit_name_is_valid(name
, UNIT_NAME_TEMPLATE
|UNIT_NAME_INSTANCE
) &&
1207 !unit_type_may_template(type
))
1208 return log_error_errno(EINVAL
, "Unit type %s cannot be templated.", unit_type_to_string(type
));
1210 if (!(flags
& SEARCH_LOAD
)) {
1211 r
= lstat(path
, &st
);
1215 if (null_or_empty(&st
))
1216 info
->type
= UNIT_FILE_TYPE_MASKED
;
1217 else if (S_ISREG(st
.st_mode
))
1218 info
->type
= UNIT_FILE_TYPE_REGULAR
;
1219 else if (S_ISLNK(st
.st_mode
))
1221 else if (S_ISDIR(st
.st_mode
))
1229 /* c is only needed if we actually load the file */
1232 fd
= open(path
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
|O_NOFOLLOW
);
1235 if (fstat(fd
, &st
) < 0)
1237 if (null_or_empty(&st
)) {
1238 info
->type
= UNIT_FILE_TYPE_MASKED
;
1241 if (S_ISDIR(st
.st_mode
))
1243 if (!S_ISREG(st
.st_mode
))
1246 f
= fdopen(fd
, "re");
1251 r
= config_parse(NULL
, path
, f
,
1253 config_item_table_lookup
, items
,
1254 true, true, false, info
);
1256 return log_debug_errno(r
, "Failed to parse %s: %m", info
->name
);
1258 info
->type
= UNIT_FILE_TYPE_REGULAR
;
1261 (int) strv_length(info
->aliases
) +
1262 (int) strv_length(info
->wanted_by
) +
1263 (int) strv_length(info
->required_by
);
1266 static int unit_file_load_or_readlink(
1268 UnitFileInstallInfo
*info
,
1270 const char *root_dir
,
1271 SearchFlags flags
) {
1273 _cleanup_free_
char *target
= NULL
;
1276 r
= unit_file_load(c
, info
, path
, flags
);
1280 /* This is a symlink, let's read it. */
1282 r
= readlink_malloc(path
, &target
);
1286 if (path_equal(target
, "/dev/null"))
1287 info
->type
= UNIT_FILE_TYPE_MASKED
;
1292 bn
= basename(target
);
1294 if (unit_name_is_valid(info
->name
, UNIT_NAME_PLAIN
)) {
1296 if (!unit_name_is_valid(bn
, UNIT_NAME_PLAIN
))
1299 } else if (unit_name_is_valid(info
->name
, UNIT_NAME_INSTANCE
)) {
1301 if (!unit_name_is_valid(bn
, UNIT_NAME_INSTANCE
|UNIT_NAME_TEMPLATE
))
1304 } else if (unit_name_is_valid(info
->name
, UNIT_NAME_TEMPLATE
)) {
1306 if (!unit_name_is_valid(bn
, UNIT_NAME_TEMPLATE
))
1311 /* Enforce that the symlink destination does not
1312 * change the unit file type. */
1314 a
= unit_name_to_type(info
->name
);
1315 b
= unit_name_to_type(bn
);
1316 if (a
< 0 || b
< 0 || a
!= b
)
1319 if (path_is_absolute(target
))
1320 /* This is an absolute path, prefix the root so that we always deal with fully qualified paths */
1321 info
->symlink_target
= prefix_root(root_dir
, target
);
1323 /* This is a relative path, take it relative to the dir the symlink is located in. */
1324 info
->symlink_target
= file_in_same_dir(path
, target
);
1325 if (!info
->symlink_target
)
1328 info
->type
= UNIT_FILE_TYPE_SYMLINK
;
1334 static int unit_file_search(
1336 UnitFileInstallInfo
*info
,
1337 const LookupPaths
*paths
,
1338 SearchFlags flags
) {
1340 _cleanup_free_
char *template = NULL
;
1347 /* Was this unit already loaded? */
1348 if (info
->type
!= _UNIT_FILE_TYPE_INVALID
)
1352 return unit_file_load_or_readlink(c
, info
, info
->path
, paths
->root_dir
, flags
);
1356 STRV_FOREACH(p
, paths
->search_path
) {
1357 _cleanup_free_
char *path
= NULL
;
1359 path
= strjoin(*p
, "/", info
->name
);
1363 r
= unit_file_load_or_readlink(c
, info
, path
, paths
->root_dir
, flags
);
1368 } else if (!IN_SET(r
, -ENOENT
, -ENOTDIR
, -EACCES
))
1372 if (unit_name_is_valid(info
->name
, UNIT_NAME_INSTANCE
)) {
1373 /* Unit file doesn't exist, however instance
1374 * enablement was requested. We will check if it is
1375 * possible to load template unit file. */
1377 r
= unit_name_template(info
->name
, &template);
1381 STRV_FOREACH(p
, paths
->search_path
) {
1382 _cleanup_free_
char *path
= NULL
;
1384 path
= strjoin(*p
, "/", template);
1388 r
= unit_file_load_or_readlink(c
, info
, path
, paths
->root_dir
, flags
);
1393 } else if (!IN_SET(r
, -ENOENT
, -ENOTDIR
, -EACCES
))
1398 log_debug("Cannot find unit %s%s%s.", info
->name
, template ? " or " : "", strempty(template));
1402 static int install_info_follow(
1404 UnitFileInstallInfo
*i
,
1405 const char *root_dir
,
1407 bool ignore_different_name
) {
1412 if (i
->type
!= UNIT_FILE_TYPE_SYMLINK
)
1414 if (!i
->symlink_target
)
1417 /* If the basename doesn't match, the caller should add a
1418 * complete new entry for this. */
1420 if (!ignore_different_name
&& !streq(basename(i
->symlink_target
), i
->name
))
1423 free_and_replace(i
->path
, i
->symlink_target
);
1424 i
->type
= _UNIT_FILE_TYPE_INVALID
;
1426 return unit_file_load_or_readlink(c
, i
, i
->path
, root_dir
, flags
);
1430 * Search for the unit file. If the unit name is a symlink, follow the symlink to the
1431 * target, maybe more than once. Propagate the instance name if present.
1433 static int install_info_traverse(
1434 UnitFileScope scope
,
1436 const LookupPaths
*paths
,
1437 UnitFileInstallInfo
*start
,
1439 UnitFileInstallInfo
**ret
) {
1441 UnitFileInstallInfo
*i
;
1449 r
= unit_file_search(c
, start
, paths
, flags
);
1454 while (i
->type
== UNIT_FILE_TYPE_SYMLINK
) {
1455 /* Follow the symlink */
1457 if (++k
> UNIT_FILE_FOLLOW_SYMLINK_MAX
)
1460 if (!(flags
& SEARCH_FOLLOW_CONFIG_SYMLINKS
)) {
1461 r
= path_is_config(paths
, i
->path
, true);
1468 r
= install_info_follow(c
, i
, paths
->root_dir
, flags
, false);
1470 _cleanup_free_
char *buffer
= NULL
;
1473 /* Target has a different name, create a new
1474 * install info object for that, and continue
1477 bn
= basename(i
->symlink_target
);
1479 if (unit_name_is_valid(i
->name
, UNIT_NAME_INSTANCE
) &&
1480 unit_name_is_valid(bn
, UNIT_NAME_TEMPLATE
)) {
1482 _cleanup_free_
char *instance
= NULL
;
1484 r
= unit_name_to_instance(i
->name
, &instance
);
1488 r
= unit_name_replace_instance(bn
, instance
, &buffer
);
1492 if (streq(buffer
, i
->name
)) {
1494 /* We filled in the instance, and the target stayed the same? If so, then let's
1495 * honour the link as it is. */
1497 r
= install_info_follow(c
, i
, paths
->root_dir
, flags
, true);
1507 r
= install_info_add(c
, bn
, NULL
, false, &i
);
1511 /* Try again, with the new target we found. */
1512 r
= unit_file_search(c
, i
, paths
, flags
);
1514 /* Translate error code to highlight this specific case */
1529 * Call install_info_add() with name_or_path as the path (if name_or_path starts with "/")
1530 * or the name (otherwise). root_dir is prepended to the path.
1532 static int install_info_add_auto(
1534 const LookupPaths
*paths
,
1535 const char *name_or_path
,
1536 UnitFileInstallInfo
**ret
) {
1539 assert(name_or_path
);
1541 if (path_is_absolute(name_or_path
)) {
1544 pp
= prefix_roota(paths
->root_dir
, name_or_path
);
1546 return install_info_add(c
, NULL
, pp
, false, ret
);
1548 return install_info_add(c
, name_or_path
, NULL
, false, ret
);
1551 static int install_info_discover(
1552 UnitFileScope scope
,
1554 const LookupPaths
*paths
,
1557 UnitFileInstallInfo
**ret
,
1558 UnitFileChange
**changes
,
1559 unsigned *n_changes
) {
1561 UnitFileInstallInfo
*i
;
1568 r
= install_info_add_auto(c
, paths
, name
, &i
);
1570 r
= install_info_traverse(scope
, c
, paths
, i
, flags
, ret
);
1573 unit_file_changes_add(changes
, n_changes
, r
, name
, NULL
);
1577 static int install_info_symlink_alias(
1578 UnitFileInstallInfo
*i
,
1579 const LookupPaths
*paths
,
1580 const char *config_path
,
1582 UnitFileChange
**changes
,
1583 unsigned *n_changes
) {
1590 assert(config_path
);
1592 STRV_FOREACH(s
, i
->aliases
) {
1593 _cleanup_free_
char *alias_path
= NULL
, *dst
= NULL
;
1595 q
= install_full_printf(i
, *s
, &dst
);
1599 alias_path
= path_make_absolute(dst
, config_path
);
1603 q
= create_symlink(paths
, i
->path
, alias_path
, force
, changes
, n_changes
);
1611 static int install_info_symlink_wants(
1612 UnitFileInstallInfo
*i
,
1613 const LookupPaths
*paths
,
1614 const char *config_path
,
1617 UnitFileChange
**changes
,
1618 unsigned *n_changes
) {
1620 _cleanup_free_
char *buf
= NULL
;
1627 assert(config_path
);
1629 if (strv_isempty(list
))
1632 if (unit_name_is_valid(i
->name
, UNIT_NAME_TEMPLATE
) && i
->default_instance
) {
1633 UnitFileInstallInfo instance
= {
1634 .type
= _UNIT_FILE_TYPE_INVALID
,
1636 _cleanup_free_
char *path
= NULL
;
1638 r
= unit_name_replace_instance(i
->name
, i
->default_instance
, &buf
);
1642 instance
.name
= buf
;
1643 r
= unit_file_search(NULL
, &instance
, paths
, SEARCH_FOLLOW_CONFIG_SYMLINKS
);
1647 path
= instance
.path
;
1648 instance
.path
= NULL
;
1650 if (instance
.type
== UNIT_FILE_TYPE_MASKED
) {
1651 unit_file_changes_add(changes
, n_changes
, -ERFKILL
, path
, NULL
);
1659 STRV_FOREACH(s
, list
) {
1660 _cleanup_free_
char *path
= NULL
, *dst
= NULL
;
1662 q
= install_full_printf(i
, *s
, &dst
);
1666 if (!unit_name_is_valid(dst
, UNIT_NAME_ANY
)) {
1671 path
= strjoin(config_path
, "/", dst
, suffix
, n
);
1675 q
= create_symlink(paths
, i
->path
, path
, true, changes
, n_changes
);
1683 static int install_info_symlink_link(
1684 UnitFileInstallInfo
*i
,
1685 const LookupPaths
*paths
,
1686 const char *config_path
,
1688 UnitFileChange
**changes
,
1689 unsigned *n_changes
) {
1691 _cleanup_free_
char *path
= NULL
;
1696 assert(config_path
);
1699 r
= in_search_path(paths
, i
->path
);
1705 path
= strjoin(config_path
, "/", i
->name
);
1709 return create_symlink(paths
, i
->path
, path
, force
, changes
, n_changes
);
1712 static int install_info_apply(
1713 UnitFileInstallInfo
*i
,
1714 const LookupPaths
*paths
,
1715 const char *config_path
,
1717 UnitFileChange
**changes
,
1718 unsigned *n_changes
) {
1724 assert(config_path
);
1726 if (i
->type
!= UNIT_FILE_TYPE_REGULAR
)
1729 r
= install_info_symlink_alias(i
, paths
, config_path
, force
, changes
, n_changes
);
1731 q
= install_info_symlink_wants(i
, paths
, config_path
, i
->wanted_by
, ".wants/", changes
, n_changes
);
1735 q
= install_info_symlink_wants(i
, paths
, config_path
, i
->required_by
, ".requires/", changes
, n_changes
);
1739 q
= install_info_symlink_link(i
, paths
, config_path
, force
, changes
, n_changes
);
1740 /* Do not count links to the unit file towards the "carries_install_info" count */
1741 if (r
== 0 && q
< 0)
1747 static int install_context_apply(
1748 UnitFileScope scope
,
1750 const LookupPaths
*paths
,
1751 const char *config_path
,
1754 UnitFileChange
**changes
,
1755 unsigned *n_changes
) {
1757 UnitFileInstallInfo
*i
;
1762 assert(config_path
);
1764 if (ordered_hashmap_isempty(c
->will_process
))
1767 r
= ordered_hashmap_ensure_allocated(&c
->have_processed
, &string_hash_ops
);
1772 while ((i
= ordered_hashmap_first(c
->will_process
))) {
1775 q
= ordered_hashmap_move_one(c
->have_processed
, c
->will_process
, i
->name
);
1779 r
= install_info_traverse(scope
, c
, paths
, i
, flags
, NULL
);
1781 unit_file_changes_add(changes
, n_changes
, r
, i
->name
, NULL
);
1785 /* We can attempt to process a masked unit when a different unit
1786 * that we were processing specifies it in Also=. */
1787 if (i
->type
== UNIT_FILE_TYPE_MASKED
) {
1788 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_IS_MASKED
, i
->path
, NULL
);
1790 /* Assume that something *could* have been enabled here,
1791 * avoid "empty [Install] section" warning. */
1796 if (i
->type
!= UNIT_FILE_TYPE_REGULAR
)
1799 q
= install_info_apply(i
, paths
, config_path
, force
, changes
, n_changes
);
1811 static int install_context_mark_for_removal(
1812 UnitFileScope scope
,
1814 const LookupPaths
*paths
,
1815 Set
**remove_symlinks_to
,
1816 const char *config_path
,
1817 UnitFileChange
**changes
,
1818 unsigned *n_changes
) {
1820 UnitFileInstallInfo
*i
;
1825 assert(config_path
);
1827 /* Marks all items for removal */
1829 if (ordered_hashmap_isempty(c
->will_process
))
1832 r
= ordered_hashmap_ensure_allocated(&c
->have_processed
, &string_hash_ops
);
1836 while ((i
= ordered_hashmap_first(c
->will_process
))) {
1838 r
= ordered_hashmap_move_one(c
->have_processed
, c
->will_process
, i
->name
);
1842 r
= install_info_traverse(scope
, c
, paths
, i
, SEARCH_LOAD
|SEARCH_FOLLOW_CONFIG_SYMLINKS
, NULL
);
1843 if (r
== -ENOLINK
) {
1844 log_debug_errno(r
, "Name %s leads to a dangling symlink, removing name.", i
->name
);
1845 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_IS_DANGLING
, i
->path
?: i
->name
, NULL
);
1846 } else if (r
== -ENOENT
) {
1848 if (i
->auxiliary
) /* some unit specified in Also= or similar is missing */
1849 log_debug_errno(r
, "Auxiliary unit of %s not found, removing name.", i
->name
);
1851 log_debug_errno(r
, "Unit %s not found, removing name.", i
->name
);
1852 unit_file_changes_add(changes
, n_changes
, r
, i
->path
?: i
->name
, NULL
);
1856 log_debug_errno(r
, "Failed to find unit %s, removing name: %m", i
->name
);
1857 unit_file_changes_add(changes
, n_changes
, r
, i
->path
?: i
->name
, NULL
);
1858 } else if (i
->type
== UNIT_FILE_TYPE_MASKED
) {
1859 log_debug("Unit file %s is masked, ignoring.", i
->name
);
1860 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_IS_MASKED
, i
->path
?: i
->name
, NULL
);
1862 } else if (i
->type
!= UNIT_FILE_TYPE_REGULAR
) {
1863 log_debug("Unit %s has type %s, ignoring.", i
->name
, unit_file_type_to_string(i
->type
) ?: "invalid");
1867 r
= mark_symlink_for_removal(remove_symlinks_to
, i
->name
);
1876 UnitFileScope scope
,
1877 UnitFileFlags flags
,
1878 const char *root_dir
,
1880 UnitFileChange
**changes
,
1881 unsigned *n_changes
) {
1883 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
1884 const char *config_path
;
1889 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
1891 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
1895 config_path
= (flags
& UNIT_FILE_RUNTIME
) ? paths
.runtime_config
: paths
.persistent_config
;
1899 STRV_FOREACH(i
, files
) {
1900 _cleanup_free_
char *path
= NULL
;
1903 if (!unit_name_is_valid(*i
, UNIT_NAME_ANY
)) {
1909 path
= path_make_absolute(*i
, config_path
);
1913 q
= create_symlink(&paths
, "/dev/null", path
, !!(flags
& UNIT_FILE_FORCE
), changes
, n_changes
);
1914 if (q
< 0 && r
>= 0)
1921 int unit_file_unmask(
1922 UnitFileScope scope
,
1923 UnitFileFlags flags
,
1924 const char *root_dir
,
1926 UnitFileChange
**changes
,
1927 unsigned *n_changes
) {
1929 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
1930 _cleanup_set_free_free_ Set
*remove_symlinks_to
= NULL
;
1931 _cleanup_strv_free_
char **todo
= NULL
;
1932 size_t n_todo
= 0, n_allocated
= 0;
1933 const char *config_path
;
1939 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
1941 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
1945 config_path
= (flags
& UNIT_FILE_RUNTIME
) ? paths
.runtime_config
: paths
.persistent_config
;
1949 dry_run
= !!(flags
& UNIT_FILE_DRY_RUN
);
1951 STRV_FOREACH(i
, files
) {
1952 _cleanup_free_
char *path
= NULL
;
1954 if (!unit_name_is_valid(*i
, UNIT_NAME_ANY
))
1957 path
= path_make_absolute(*i
, config_path
);
1961 r
= null_or_empty_path(path
);
1969 if (!GREEDY_REALLOC0(todo
, n_allocated
, n_todo
+ 2))
1972 todo
[n_todo
] = strdup(*i
);
1982 STRV_FOREACH(i
, todo
) {
1983 _cleanup_free_
char *path
= NULL
;
1986 path
= path_make_absolute(*i
, config_path
);
1990 if (!dry_run
&& unlink(path
) < 0) {
1991 if (errno
!= ENOENT
) {
1994 unit_file_changes_add(changes
, n_changes
, -errno
, path
, NULL
);
2000 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_UNLINK
, path
, NULL
);
2002 rp
= skip_root(&paths
, path
);
2003 q
= mark_symlink_for_removal(&remove_symlinks_to
, rp
?: path
);
2008 q
= remove_marked_symlinks(remove_symlinks_to
, config_path
, &paths
, dry_run
, changes
, n_changes
);
2016 UnitFileScope scope
,
2017 UnitFileFlags flags
,
2018 const char *root_dir
,
2020 UnitFileChange
**changes
,
2021 unsigned *n_changes
) {
2023 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2024 _cleanup_strv_free_
char **todo
= NULL
;
2025 size_t n_todo
= 0, n_allocated
= 0;
2026 const char *config_path
;
2031 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2033 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2037 config_path
= (flags
& UNIT_FILE_RUNTIME
) ? paths
.runtime_config
: paths
.persistent_config
;
2041 STRV_FOREACH(i
, files
) {
2042 _cleanup_free_
char *full
= NULL
;
2046 if (!path_is_absolute(*i
))
2050 if (!unit_name_is_valid(fn
, UNIT_NAME_ANY
))
2053 full
= prefix_root(paths
.root_dir
, *i
);
2057 if (lstat(full
, &st
) < 0)
2059 if (S_ISLNK(st
.st_mode
))
2061 if (S_ISDIR(st
.st_mode
))
2063 if (!S_ISREG(st
.st_mode
))
2066 q
= in_search_path(&paths
, *i
);
2072 if (!GREEDY_REALLOC0(todo
, n_allocated
, n_todo
+ 2))
2075 todo
[n_todo
] = strdup(*i
);
2085 STRV_FOREACH(i
, todo
) {
2086 _cleanup_free_
char *new_path
= NULL
;
2088 new_path
= path_make_absolute(basename(*i
), config_path
);
2092 q
= create_symlink(&paths
, *i
, new_path
, !!(flags
& UNIT_FILE_FORCE
), changes
, n_changes
);
2093 if (q
< 0 && r
>= 0)
2100 static int path_shall_revert(const LookupPaths
*paths
, const char *path
) {
2106 /* Checks whether the path is one where the drop-in directories shall be removed. */
2108 r
= path_is_config(paths
, path
, true);
2112 r
= path_is_control(paths
, path
);
2116 return path_is_transient(paths
, path
);
2119 int unit_file_revert(
2120 UnitFileScope scope
,
2121 const char *root_dir
,
2123 UnitFileChange
**changes
,
2124 unsigned *n_changes
) {
2126 _cleanup_set_free_free_ Set
*remove_symlinks_to
= NULL
;
2127 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2128 _cleanup_strv_free_
char **todo
= NULL
;
2129 size_t n_todo
= 0, n_allocated
= 0;
2133 /* Puts a unit file back into vendor state. This means:
2135 * a) we remove all drop-in snippets added by the user ("config"), add to transient units ("transient"), and
2136 * added via "systemctl set-property" ("control"), but not if the drop-in is generated ("generated").
2138 * c) if there's a vendor unit file (i.e. one in /usr) we remove any configured overriding unit files (i.e. in
2139 * "config", but not in "transient" or "control" or even "generated").
2141 * We remove all that in both the runtime and the persistent directories, if that applies.
2144 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2148 STRV_FOREACH(i
, files
) {
2149 bool has_vendor
= false;
2152 if (!unit_name_is_valid(*i
, UNIT_NAME_ANY
))
2155 STRV_FOREACH(p
, paths
.search_path
) {
2156 _cleanup_free_
char *path
= NULL
, *dropin
= NULL
;
2159 path
= path_make_absolute(*i
, *p
);
2163 r
= lstat(path
, &st
);
2165 if (errno
!= ENOENT
)
2167 } else if (S_ISREG(st
.st_mode
)) {
2168 /* Check if there's a vendor version */
2169 r
= path_is_vendor(&paths
, path
);
2176 dropin
= strappend(path
, ".d");
2180 r
= lstat(dropin
, &st
);
2182 if (errno
!= ENOENT
)
2184 } else if (S_ISDIR(st
.st_mode
)) {
2185 /* Remove the drop-ins */
2186 r
= path_shall_revert(&paths
, dropin
);
2190 if (!GREEDY_REALLOC0(todo
, n_allocated
, n_todo
+ 2))
2193 todo
[n_todo
++] = dropin
;
2202 /* OK, there's a vendor version, hence drop all configuration versions */
2203 STRV_FOREACH(p
, paths
.search_path
) {
2204 _cleanup_free_
char *path
= NULL
;
2207 path
= path_make_absolute(*i
, *p
);
2211 r
= lstat(path
, &st
);
2213 if (errno
!= ENOENT
)
2215 } else if (S_ISREG(st
.st_mode
) || S_ISLNK(st
.st_mode
)) {
2216 r
= path_is_config(&paths
, path
, true);
2220 if (!GREEDY_REALLOC0(todo
, n_allocated
, n_todo
+ 2))
2223 todo
[n_todo
++] = path
;
2233 STRV_FOREACH(i
, todo
) {
2234 _cleanup_strv_free_
char **fs
= NULL
;
2238 (void) get_files_in_directory(*i
, &fs
);
2240 q
= rm_rf(*i
, REMOVE_ROOT
|REMOVE_PHYSICAL
);
2241 if (q
< 0 && q
!= -ENOENT
&& r
>= 0) {
2246 STRV_FOREACH(j
, fs
) {
2247 _cleanup_free_
char *t
= NULL
;
2249 t
= strjoin(*i
, "/", *j
);
2253 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_UNLINK
, t
, NULL
);
2256 unit_file_changes_add(changes
, n_changes
, UNIT_FILE_UNLINK
, *i
, NULL
);
2258 rp
= skip_root(&paths
, *i
);
2259 q
= mark_symlink_for_removal(&remove_symlinks_to
, rp
?: *i
);
2264 q
= remove_marked_symlinks(remove_symlinks_to
, paths
.runtime_config
, &paths
, false, changes
, n_changes
);
2268 q
= remove_marked_symlinks(remove_symlinks_to
, paths
.persistent_config
, &paths
, false, changes
, n_changes
);
2275 int unit_file_add_dependency(
2276 UnitFileScope scope
,
2277 UnitFileFlags flags
,
2278 const char *root_dir
,
2282 UnitFileChange
**changes
,
2283 unsigned *n_changes
) {
2285 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2286 _cleanup_(install_context_done
) InstallContext c
= {};
2287 UnitFileInstallInfo
*i
, *target_info
;
2288 const char *config_path
;
2293 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2296 if (!IN_SET(dep
, UNIT_WANTS
, UNIT_REQUIRES
))
2299 if (!unit_name_is_valid(target
, UNIT_NAME_ANY
))
2302 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2306 config_path
= (flags
& UNIT_FILE_RUNTIME
) ? paths
.runtime_config
: paths
.persistent_config
;
2310 r
= install_info_discover(scope
, &c
, &paths
, target
, SEARCH_FOLLOW_CONFIG_SYMLINKS
,
2311 &target_info
, changes
, n_changes
);
2314 r
= install_info_may_process(target_info
, &paths
, changes
, n_changes
);
2318 assert(target_info
->type
== UNIT_FILE_TYPE_REGULAR
);
2320 STRV_FOREACH(f
, files
) {
2323 r
= install_info_discover(scope
, &c
, &paths
, *f
, SEARCH_FOLLOW_CONFIG_SYMLINKS
,
2324 &i
, changes
, n_changes
);
2327 r
= install_info_may_process(i
, &paths
, changes
, n_changes
);
2331 assert(i
->type
== UNIT_FILE_TYPE_REGULAR
);
2333 /* We didn't actually load anything from the unit
2334 * file, but instead just add in our new symlink to
2337 if (dep
== UNIT_WANTS
)
2340 l
= &i
->required_by
;
2343 *l
= strv_new(target_info
->name
, NULL
);
2348 return install_context_apply(scope
, &c
, &paths
, config_path
, !!(flags
& UNIT_FILE_FORCE
), SEARCH_FOLLOW_CONFIG_SYMLINKS
, changes
, n_changes
);
2351 int unit_file_enable(
2352 UnitFileScope scope
,
2353 UnitFileFlags flags
,
2354 const char *root_dir
,
2356 UnitFileChange
**changes
,
2357 unsigned *n_changes
) {
2359 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2360 _cleanup_(install_context_done
) InstallContext c
= {};
2361 const char *config_path
;
2362 UnitFileInstallInfo
*i
;
2367 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2369 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2373 config_path
= (flags
& UNIT_FILE_RUNTIME
) ? paths
.runtime_config
: paths
.persistent_config
;
2377 STRV_FOREACH(f
, files
) {
2378 r
= install_info_discover(scope
, &c
, &paths
, *f
, SEARCH_LOAD
|SEARCH_FOLLOW_CONFIG_SYMLINKS
,
2379 &i
, changes
, n_changes
);
2382 r
= install_info_may_process(i
, &paths
, changes
, n_changes
);
2386 assert(i
->type
== UNIT_FILE_TYPE_REGULAR
);
2389 /* This will return the number of symlink rules that were
2390 supposed to be created, not the ones actually created. This
2391 is useful to determine whether the passed files had any
2392 installation data at all. */
2394 return install_context_apply(scope
, &c
, &paths
, config_path
, !!(flags
& UNIT_FILE_FORCE
), SEARCH_LOAD
, changes
, n_changes
);
2397 int unit_file_disable(
2398 UnitFileScope scope
,
2399 UnitFileFlags flags
,
2400 const char *root_dir
,
2402 UnitFileChange
**changes
,
2403 unsigned *n_changes
) {
2405 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2406 _cleanup_(install_context_done
) InstallContext c
= {};
2407 _cleanup_set_free_free_ Set
*remove_symlinks_to
= NULL
;
2408 const char *config_path
;
2413 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2415 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2419 config_path
= (flags
& UNIT_FILE_RUNTIME
) ? paths
.runtime_config
: paths
.persistent_config
;
2423 STRV_FOREACH(i
, files
) {
2424 if (!unit_name_is_valid(*i
, UNIT_NAME_ANY
))
2427 r
= install_info_add(&c
, *i
, NULL
, false, NULL
);
2432 r
= install_context_mark_for_removal(scope
, &c
, &paths
, &remove_symlinks_to
, config_path
, changes
, n_changes
);
2436 return remove_marked_symlinks(remove_symlinks_to
, config_path
, &paths
, !!(flags
& UNIT_FILE_DRY_RUN
), changes
, n_changes
);
2439 int unit_file_reenable(
2440 UnitFileScope scope
,
2441 UnitFileFlags flags
,
2442 const char *root_dir
,
2444 UnitFileChange
**changes
,
2445 unsigned *n_changes
) {
2451 /* First, we invoke the disable command with only the basename... */
2452 l
= strv_length(files
);
2453 n
= newa(char*, l
+1);
2454 for (i
= 0; i
< l
; i
++)
2455 n
[i
] = basename(files
[i
]);
2458 r
= unit_file_disable(scope
, flags
, root_dir
, n
, changes
, n_changes
);
2462 /* But the enable command with the full name */
2463 return unit_file_enable(scope
, flags
, root_dir
, files
, changes
, n_changes
);
2466 int unit_file_set_default(
2467 UnitFileScope scope
,
2468 UnitFileFlags flags
,
2469 const char *root_dir
,
2471 UnitFileChange
**changes
,
2472 unsigned *n_changes
) {
2474 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2475 _cleanup_(install_context_done
) InstallContext c
= {};
2476 UnitFileInstallInfo
*i
;
2477 const char *new_path
;
2481 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2484 if (unit_name_to_type(name
) != UNIT_TARGET
) /* this also validates the name */
2486 if (streq(name
, SPECIAL_DEFAULT_TARGET
))
2489 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2493 r
= install_info_discover(scope
, &c
, &paths
, name
, 0, &i
, changes
, n_changes
);
2496 r
= install_info_may_process(i
, &paths
, changes
, n_changes
);
2500 new_path
= strjoina(paths
.persistent_config
, "/" SPECIAL_DEFAULT_TARGET
);
2501 return create_symlink(&paths
, i
->path
, new_path
, !!(flags
& UNIT_FILE_FORCE
), changes
, n_changes
);
2504 int unit_file_get_default(
2505 UnitFileScope scope
,
2506 const char *root_dir
,
2509 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2510 _cleanup_(install_context_done
) InstallContext c
= {};
2511 UnitFileInstallInfo
*i
;
2516 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2519 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2523 r
= install_info_discover(scope
, &c
, &paths
, SPECIAL_DEFAULT_TARGET
, SEARCH_FOLLOW_CONFIG_SYMLINKS
,
2527 r
= install_info_may_process(i
, &paths
, NULL
, 0);
2531 n
= strdup(i
->name
);
2539 static int unit_file_lookup_state(
2540 UnitFileScope scope
,
2541 const LookupPaths
*paths
,
2543 UnitFileState
*ret
) {
2545 _cleanup_(install_context_done
) InstallContext c
= {};
2546 UnitFileInstallInfo
*i
;
2547 UnitFileState state
;
2553 if (!unit_name_is_valid(name
, UNIT_NAME_ANY
))
2556 r
= install_info_discover(scope
, &c
, paths
, name
, SEARCH_LOAD
|SEARCH_FOLLOW_CONFIG_SYMLINKS
,
2561 /* Shortcut things, if the caller just wants to know if this unit exists. */
2567 case UNIT_FILE_TYPE_MASKED
:
2568 r
= path_is_runtime(paths
, i
->path
, true);
2572 state
= r
> 0 ? UNIT_FILE_MASKED_RUNTIME
: UNIT_FILE_MASKED
;
2575 case UNIT_FILE_TYPE_REGULAR
:
2576 r
= path_is_generator(paths
, i
->path
);
2580 state
= UNIT_FILE_GENERATED
;
2584 r
= path_is_transient(paths
, i
->path
);
2588 state
= UNIT_FILE_TRANSIENT
;
2592 r
= find_symlinks_in_scope(paths
, i
->name
, &state
);
2596 if (UNIT_FILE_INSTALL_INFO_HAS_RULES(i
))
2597 state
= UNIT_FILE_DISABLED
;
2598 else if (UNIT_FILE_INSTALL_INFO_HAS_ALSO(i
))
2599 state
= UNIT_FILE_INDIRECT
;
2601 state
= UNIT_FILE_STATIC
;
2607 assert_not_reached("Unexpect unit file type.");
2614 int unit_file_get_state(
2615 UnitFileScope scope
,
2616 const char *root_dir
,
2618 UnitFileState
*ret
) {
2620 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2624 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2627 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2631 return unit_file_lookup_state(scope
, &paths
, name
, ret
);
2634 int unit_file_exists(UnitFileScope scope
, const LookupPaths
*paths
, const char *name
) {
2635 _cleanup_(install_context_done
) InstallContext c
= {};
2641 if (!unit_name_is_valid(name
, UNIT_NAME_ANY
))
2644 r
= install_info_discover(scope
, &c
, paths
, name
, 0, NULL
, NULL
, NULL
);
2653 static int read_presets(UnitFileScope scope
, const char *root_dir
, Presets
*presets
) {
2654 _cleanup_(presets_freep
) Presets ps
= {};
2655 size_t n_allocated
= 0;
2656 _cleanup_strv_free_
char **files
= NULL
;
2661 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2664 if (scope
== UNIT_FILE_SYSTEM
)
2665 r
= conf_files_list(&files
, ".preset", root_dir
, 0,
2666 "/etc/systemd/system-preset",
2667 "/usr/local/lib/systemd/system-preset",
2668 "/usr/lib/systemd/system-preset",
2669 #ifdef HAVE_SPLIT_USR
2670 "/lib/systemd/system-preset",
2673 else if (scope
== UNIT_FILE_GLOBAL
)
2674 r
= conf_files_list(&files
, ".preset", root_dir
, 0,
2675 "/etc/systemd/user-preset",
2676 "/usr/local/lib/systemd/user-preset",
2677 "/usr/lib/systemd/user-preset",
2680 *presets
= (Presets
){};
2688 STRV_FOREACH(p
, files
) {
2689 _cleanup_fclose_
FILE *f
;
2690 char line
[LINE_MAX
];
2693 f
= fopen(*p
, "re");
2695 if (errno
== ENOENT
)
2701 FOREACH_LINE(line
, f
, return -errno
) {
2702 PresetRule rule
= {};
2703 const char *parameter
;
2711 if (strchr(COMMENTS
, *l
))
2714 parameter
= first_word(l
, "enable");
2718 pattern
= strdup(parameter
);
2722 rule
= (PresetRule
) {
2724 .action
= PRESET_ENABLE
,
2728 parameter
= first_word(l
, "disable");
2732 pattern
= strdup(parameter
);
2736 rule
= (PresetRule
) {
2738 .action
= PRESET_DISABLE
,
2743 if (!GREEDY_REALLOC(ps
.rules
, n_allocated
, ps
.n_rules
+ 1))
2746 ps
.rules
[ps
.n_rules
++] = rule
;
2750 log_syntax(NULL
, LOG_WARNING
, *p
, n
, 0, "Couldn't parse line '%s'. Ignoring.", line
);
2760 static int query_presets(const char *name
, const Presets presets
) {
2761 PresetAction action
= PRESET_UNKNOWN
;
2764 if (!unit_name_is_valid(name
, UNIT_NAME_ANY
))
2767 for (i
= 0; i
< presets
.n_rules
; i
++)
2768 if (fnmatch(presets
.rules
[i
].pattern
, name
, FNM_NOESCAPE
) == 0) {
2769 action
= presets
.rules
[i
].action
;
2774 case PRESET_UNKNOWN
:
2775 log_debug("Preset files don't specify rule for %s. Enabling.", name
);
2778 log_debug("Preset files say enable %s.", name
);
2780 case PRESET_DISABLE
:
2781 log_debug("Preset files say disable %s.", name
);
2784 assert_not_reached("invalid preset action");
2788 int unit_file_query_preset(UnitFileScope scope
, const char *root_dir
, const char *name
) {
2789 _cleanup_(presets_freep
) Presets presets
= {};
2792 r
= read_presets(scope
, root_dir
, &presets
);
2796 return query_presets(name
, presets
);
2799 static int execute_preset(
2800 UnitFileScope scope
,
2801 InstallContext
*plus
,
2802 InstallContext
*minus
,
2803 const LookupPaths
*paths
,
2804 const char *config_path
,
2806 UnitFilePresetMode mode
,
2808 UnitFileChange
**changes
,
2809 unsigned *n_changes
) {
2816 assert(config_path
);
2818 if (mode
!= UNIT_FILE_PRESET_ENABLE_ONLY
) {
2819 _cleanup_set_free_free_ Set
*remove_symlinks_to
= NULL
;
2821 r
= install_context_mark_for_removal(scope
, minus
, paths
, &remove_symlinks_to
, config_path
, changes
, n_changes
);
2825 r
= remove_marked_symlinks(remove_symlinks_to
, config_path
, paths
, false, changes
, n_changes
);
2829 if (mode
!= UNIT_FILE_PRESET_DISABLE_ONLY
) {
2832 /* Returns number of symlinks that where supposed to be installed. */
2833 q
= install_context_apply(scope
, plus
, paths
, config_path
, force
, SEARCH_LOAD
, changes
, n_changes
);
2845 static int preset_prepare_one(
2846 UnitFileScope scope
,
2847 InstallContext
*plus
,
2848 InstallContext
*minus
,
2852 UnitFileChange
**changes
,
2853 unsigned *n_changes
) {
2855 _cleanup_(install_context_done
) InstallContext tmp
= {};
2856 UnitFileInstallInfo
*i
;
2859 if (install_info_find(plus
, name
) || install_info_find(minus
, name
))
2862 r
= install_info_discover(scope
, &tmp
, paths
, name
, SEARCH_FOLLOW_CONFIG_SYMLINKS
,
2863 &i
, changes
, n_changes
);
2866 if (!streq(name
, i
->name
)) {
2867 log_debug("Skipping %s because is an alias for %s", name
, i
->name
);
2871 r
= query_presets(name
, presets
);
2876 r
= install_info_discover(scope
, plus
, paths
, name
, SEARCH_LOAD
|SEARCH_FOLLOW_CONFIG_SYMLINKS
,
2877 &i
, changes
, n_changes
);
2881 r
= install_info_may_process(i
, paths
, changes
, n_changes
);
2885 r
= install_info_discover(scope
, minus
, paths
, name
, SEARCH_FOLLOW_CONFIG_SYMLINKS
,
2886 &i
, changes
, n_changes
);
2891 int unit_file_preset(
2892 UnitFileScope scope
,
2893 UnitFileFlags flags
,
2894 const char *root_dir
,
2896 UnitFilePresetMode mode
,
2897 UnitFileChange
**changes
,
2898 unsigned *n_changes
) {
2900 _cleanup_(install_context_done
) InstallContext plus
= {}, minus
= {};
2901 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2902 _cleanup_(presets_freep
) Presets presets
= {};
2903 const char *config_path
;
2908 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2909 assert(mode
< _UNIT_FILE_PRESET_MAX
);
2911 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2915 config_path
= (flags
& UNIT_FILE_RUNTIME
) ? paths
.runtime_config
: paths
.persistent_config
;
2919 r
= read_presets(scope
, root_dir
, &presets
);
2923 STRV_FOREACH(i
, files
) {
2924 r
= preset_prepare_one(scope
, &plus
, &minus
, &paths
, *i
, presets
, changes
, n_changes
);
2929 return execute_preset(scope
, &plus
, &minus
, &paths
, config_path
, files
, mode
, !!(flags
& UNIT_FILE_FORCE
), changes
, n_changes
);
2932 int unit_file_preset_all(
2933 UnitFileScope scope
,
2934 UnitFileFlags flags
,
2935 const char *root_dir
,
2936 UnitFilePresetMode mode
,
2937 UnitFileChange
**changes
,
2938 unsigned *n_changes
) {
2940 _cleanup_(install_context_done
) InstallContext plus
= {}, minus
= {};
2941 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
2942 _cleanup_(presets_freep
) Presets presets
= {};
2943 const char *config_path
= NULL
;
2948 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
2949 assert(mode
< _UNIT_FILE_PRESET_MAX
);
2951 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
2955 config_path
= (flags
& UNIT_FILE_RUNTIME
) ? paths
.runtime_config
: paths
.persistent_config
;
2959 r
= read_presets(scope
, root_dir
, &presets
);
2963 STRV_FOREACH(i
, paths
.search_path
) {
2964 _cleanup_closedir_
DIR *d
= NULL
;
2969 if (errno
== ENOENT
)
2975 FOREACH_DIRENT(de
, d
, return -errno
) {
2977 if (!unit_name_is_valid(de
->d_name
, UNIT_NAME_ANY
))
2980 dirent_ensure_type(d
, de
);
2982 if (!IN_SET(de
->d_type
, DT_LNK
, DT_REG
))
2985 /* we don't pass changes[] in, because we want to handle errors on our own */
2986 r
= preset_prepare_one(scope
, &plus
, &minus
, &paths
, de
->d_name
, presets
, NULL
, 0);
2988 r
= unit_file_changes_add(changes
, n_changes
,
2989 UNIT_FILE_IS_MASKED
, de
->d_name
, NULL
);
2990 else if (r
== -ENOLINK
)
2991 r
= unit_file_changes_add(changes
, n_changes
,
2992 UNIT_FILE_IS_DANGLING
, de
->d_name
, NULL
);
2998 return execute_preset(scope
, &plus
, &minus
, &paths
, config_path
, NULL
, mode
, !!(flags
& UNIT_FILE_FORCE
), changes
, n_changes
);
3001 static void unit_file_list_free_one(UnitFileList
*f
) {
3009 Hashmap
* unit_file_list_free(Hashmap
*h
) {
3012 while ((i
= hashmap_steal_first(h
)))
3013 unit_file_list_free_one(i
);
3015 return hashmap_free(h
);
3018 DEFINE_TRIVIAL_CLEANUP_FUNC(UnitFileList
*, unit_file_list_free_one
);
3020 int unit_file_get_list(
3021 UnitFileScope scope
,
3022 const char *root_dir
,
3027 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
3032 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
3035 r
= lookup_paths_init(&paths
, scope
, 0, root_dir
);
3039 STRV_FOREACH(i
, paths
.search_path
) {
3040 _cleanup_closedir_
DIR *d
= NULL
;
3045 if (errno
== ENOENT
)
3047 if (IN_SET(errno
, ENOTDIR
, EACCES
)) {
3048 log_debug_errno(errno
, "Failed to open \"%s\": %m", *i
);
3055 FOREACH_DIRENT(de
, d
, return -errno
) {
3056 _cleanup_(unit_file_list_free_onep
) UnitFileList
*f
= NULL
;
3058 if (!unit_name_is_valid(de
->d_name
, UNIT_NAME_ANY
))
3061 if (!strv_fnmatch_or_empty(patterns
, de
->d_name
, FNM_NOESCAPE
))
3064 if (hashmap_get(h
, de
->d_name
))
3067 dirent_ensure_type(d
, de
);
3069 if (!IN_SET(de
->d_type
, DT_LNK
, DT_REG
))
3072 f
= new0(UnitFileList
, 1);
3076 f
->path
= path_make_absolute(de
->d_name
, *i
);
3080 r
= unit_file_lookup_state(scope
, &paths
, de
->d_name
, &f
->state
);
3082 f
->state
= UNIT_FILE_BAD
;
3084 if (!strv_isempty(states
) &&
3085 !strv_contains(states
, unit_file_state_to_string(f
->state
)))
3088 r
= hashmap_put(h
, basename(f
->path
), f
);
3092 f
= NULL
; /* prevent cleanup */
3099 static const char* const unit_file_state_table
[_UNIT_FILE_STATE_MAX
] = {
3100 [UNIT_FILE_ENABLED
] = "enabled",
3101 [UNIT_FILE_ENABLED_RUNTIME
] = "enabled-runtime",
3102 [UNIT_FILE_LINKED
] = "linked",
3103 [UNIT_FILE_LINKED_RUNTIME
] = "linked-runtime",
3104 [UNIT_FILE_MASKED
] = "masked",
3105 [UNIT_FILE_MASKED_RUNTIME
] = "masked-runtime",
3106 [UNIT_FILE_STATIC
] = "static",
3107 [UNIT_FILE_DISABLED
] = "disabled",
3108 [UNIT_FILE_INDIRECT
] = "indirect",
3109 [UNIT_FILE_GENERATED
] = "generated",
3110 [UNIT_FILE_TRANSIENT
] = "transient",
3111 [UNIT_FILE_BAD
] = "bad",
3114 DEFINE_STRING_TABLE_LOOKUP(unit_file_state
, UnitFileState
);
3116 static const char* const unit_file_change_type_table
[_UNIT_FILE_CHANGE_TYPE_MAX
] = {
3117 [UNIT_FILE_SYMLINK
] = "symlink",
3118 [UNIT_FILE_UNLINK
] = "unlink",
3119 [UNIT_FILE_IS_MASKED
] = "masked",
3120 [UNIT_FILE_IS_DANGLING
] = "dangling",
3123 DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type
, UnitFileChangeType
);
3125 static const char* const unit_file_preset_mode_table
[_UNIT_FILE_PRESET_MAX
] = {
3126 [UNIT_FILE_PRESET_FULL
] = "full",
3127 [UNIT_FILE_PRESET_ENABLE_ONLY
] = "enable-only",
3128 [UNIT_FILE_PRESET_DISABLE_ONLY
] = "disable-only",
3131 DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode
, UnitFilePresetMode
);