X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Finstall.c;h=d2dd27680309b424f3d89588597f8d8c6beab9c4;hb=b32ff512191bf873266ee8067f6f6c8a30c96a5e;hp=edf4d2a9fe979b8dbc4c7e09e05938a6655dea20;hpb=db5c0122853a9ecf1cc92e6593461932df2fa866;p=elogind.git diff --git a/src/shared/install.c b/src/shared/install.c index edf4d2a9f..d2dd27680 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -1413,7 +1413,9 @@ static int install_context_mark_for_removal( assert_se(hashmap_move_one(c->have_installed, c->will_install, i->name) == 0); q = unit_file_search(c, i, paths, root_dir, false); - if (q < 0) { + if (q == -ENOENT) { + /* do nothing */ + } else if (q < 0) { if (r >= 0) r = q; @@ -1570,6 +1572,92 @@ int unit_file_reenable( return r; } +int unit_file_set_default( + UnitFileScope scope, + const char *root_dir, + char *file, + UnitFileChange **changes, + unsigned *n_changes) { + + _cleanup_lookup_paths_free_ LookupPaths paths = {}; + _cleanup_install_context_done_ InstallContext c = {}; + _cleanup_free_ char *config_path = NULL; + char *path; + int r; + InstallInfo *i = NULL; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + + if (unit_name_to_type(file) != UNIT_TARGET) + return -EINVAL; + + r = lookup_paths_init_from_scope(&paths, scope); + if (r < 0) + return r; + + r = get_config_path(scope, false, root_dir, &config_path); + if (r < 0) + return r; + + r = install_info_add_auto(&c, file); + if (r < 0) + return r; + + i = (InstallInfo*)hashmap_first(c.will_install); + + r = unit_file_search(&c, i, &paths, root_dir, false); + if (r < 0) + return r; + + path = strappenda(config_path, "/default.target"); + r = create_symlink(i->path, path, true, changes, n_changes); + if (r < 0) + return r; + + return 0; +} + +int unit_file_get_default( + UnitFileScope scope, + const char *root_dir, + char **name) { + + _cleanup_lookup_paths_free_ LookupPaths paths = {}; + char **p; + int r; + + r = lookup_paths_init_from_scope(&paths, scope); + if (r < 0) + return r; + + STRV_FOREACH(p, paths.unit_path) { + _cleanup_free_ char *path = NULL, *tmp = NULL; + + if (isempty(root_dir)) + path = strappend(*p, "/default.target"); + else + path = strjoin(root_dir, "/", *p, "/default.target", NULL); + + if (!path) + return -ENOMEM; + + r = readlink_malloc(path, &tmp); + if (r == -ENOENT) + continue; + else if (r < 0) + return r; + + *name = strdup(path_get_file_name(tmp)); + if (!*name) + return -ENOMEM; + + return 0; + } + + return -ENOENT; +} + UnitFileState unit_file_get_state( UnitFileScope scope, const char *root_dir, @@ -1609,24 +1697,29 @@ UnitFileState unit_file_get_state( if (!path) return -ENOMEM; + /* + * Search for a unit file in our default paths, to + * be sure, that there are no broken symlinks. + */ if (lstat(path, &st) < 0) { r = -errno; - if (errno == ENOENT) - continue; - - return -errno; - } + if (errno != ENOENT) + return r; - if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) - return -ENOENT; + if (!unit_name_is_instance(name)) + continue; + } else { + if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) + return -ENOENT; - r = null_or_empty_path(path); - if (r < 0 && r != -ENOENT) - return r; - else if (r > 0) { - state = path_startswith(*i, "/run") ? - UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED; - return state; + r = null_or_empty_path(path); + if (r < 0 && r != -ENOENT) + return r; + else if (r > 0) { + state = path_startswith(*i, "/run") ? + UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED; + return state; + } } r = find_symlinks_in_scope(scope, root_dir, name, &state);