chiark / gitweb /
install: simplify and clarify disabling logic for instanced units
[elogind.git] / src / shared / install.c
index f5620633c08a824e92a872332924c6e21bbd30ad..40dc7bebe8b6a438fe0fbb59dc422186223d13cf 100644 (file)
@@ -194,10 +194,10 @@ static int remove_marked_symlinks_fd(
                 bool *deleted,
                 UnitFileChange **changes,
                 unsigned *n_changes,
-                char** files) {
+                char** instance_whitelist) {
 
-        int r = 0;
         _cleanup_closedir_ DIR *d = NULL;
+        int r = 0;
 
         assert(remove_symlinks_to);
         assert(fd >= 0);
@@ -252,9 +252,8 @@ static int remove_marked_symlinks_fd(
                         }
 
                         /* This will close nfd, regardless whether it succeeds or not */
-                        q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, deleted, changes, n_changes, files);
-
-                        if (r == 0)
+                        q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, deleted, changes, n_changes, instance_whitelist);
+                        if (q < 0 && r == 0)
                                 r = q;
 
                 } else if (de->d_type == DT_LNK) {
@@ -262,6 +261,14 @@ static int remove_marked_symlinks_fd(
                         int q;
                         bool found;
 
+                        if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
+                                continue;
+
+                        if (unit_name_is_instance(de->d_name) &&
+                            instance_whitelist &&
+                            !strv_contains(instance_whitelist, de->d_name))
+                                continue;
+
                         p = path_make_absolute(de->d_name, path);
                         if (!p)
                                 return -ENOMEM;
@@ -280,30 +287,29 @@ static int remove_marked_symlinks_fd(
                                 set_get(remove_symlinks_to, dest) ||
                                 set_get(remove_symlinks_to, basename(dest));
 
-                        if (unit_name_is_instance(p))
-                                found = found && strv_contains(files, basename(p));
-
                         if (found) {
 
                                 if (unlink(p) < 0 && errno != ENOENT) {
 
                                         if (r == 0)
                                                 r = -errno;
-                                } else {
-                                        rmdir_parents(p, config_path);
-                                        path_kill_slashes(p);
+                                        continue;
+                                }
 
-                                        add_file_change(changes, n_changes, UNIT_FILE_UNLINK, p, NULL);
+                                rmdir_parents(p, config_path);
 
-                                        if (!set_get(remove_symlinks_to, p)) {
+                                path_kill_slashes(p);
 
-                                                q = mark_symlink_for_removal(&remove_symlinks_to, p);
-                                                if (q < 0) {
-                                                        if (r == 0)
-                                                                r = q;
-                                                } else
-                                                        *deleted = true;
-                                        }
+                                add_file_change(changes, n_changes, UNIT_FILE_UNLINK, p, NULL);
+
+                                if (!set_get(remove_symlinks_to, p)) {
+
+                                        q = mark_symlink_for_removal(&remove_symlinks_to, p);
+                                        if (q < 0) {
+                                                if (r == 0)
+                                                        r = q;
+                                        } else
+                                                *deleted = true;
                                 }
                         }
                 }
@@ -317,9 +323,10 @@ static int remove_marked_symlinks(
                 const char *config_path,
                 UnitFileChange **changes,
                 unsigned *n_changes,
-                char** files) {
+                char** instance_whitelist) {
 
-        int fd, r = 0;
+        _cleanup_close_ int fd = -1;
+        int r = 0;
         bool deleted;
 
         assert(config_path);
@@ -342,13 +349,11 @@ static int remove_marked_symlinks(
                 }
 
                 /* This takes possession of cfd and closes it */
-                q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, &deleted, changes, n_changes, files);
+                q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, &deleted, changes, n_changes, instance_whitelist);
                 if (r == 0)
                         r = q;
         } while (deleted);
 
-        safe_close(fd);
-
         return r;
 }
 
@@ -1830,11 +1835,11 @@ int unit_file_preset(
                 UnitFileChange **changes,
                 unsigned *n_changes) {
 
-        _cleanup_lookup_paths_free_ LookupPaths paths = {};
         _cleanup_install_context_done_ InstallContext plus = {}, minus = {};
-        char **i;
-        _cleanup_free_ char *config_path = NULL;
         _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
+        _cleanup_lookup_paths_free_ LookupPaths paths = {};
+        _cleanup_free_ char *config_path = NULL;
+        char **i;
         int r, q;
 
         assert(scope >= 0);
@@ -1861,16 +1866,13 @@ int unit_file_preset(
                         r = install_info_add_auto(&plus, *i);
                 else
                         r = install_info_add_auto(&minus, *i);
-
                 if (r < 0)
                         return r;
         }
 
-        r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to,
-                                             config_path, root_dir);
+        r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
 
-        q = remove_marked_symlinks(remove_symlinks_to, config_path,
-                                   changes, n_changes, files);
+        q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
         if (r == 0)
                 r = q;
 
@@ -1899,8 +1901,6 @@ int unit_file_get_list(
 
         _cleanup_lookup_paths_free_ LookupPaths paths = {};
         char **i;
-        _cleanup_free_ char *buf = NULL;
-        _cleanup_closedir_ DIR *d = NULL;
         int r;
 
         assert(scope >= 0);
@@ -1915,22 +1915,19 @@ int unit_file_get_list(
                 return r;
 
         STRV_FOREACH(i, paths.unit_path) {
+                _cleanup_closedir_ DIR *d = NULL;
+                _cleanup_free_ char *buf = NULL;
                 const char *units_dir;
 
-                free(buf);
-                buf = NULL;
-
-                if (root_dir) {
-                        if (asprintf(&buf, "%s/%s", root_dir, *i) < 0)
+                if (!isempty(root_dir)) {
+                        buf = strjoin(root_dir, "/", *i, NULL);
+                        if (!buf)
                                 return -ENOMEM;
 
                         units_dir = buf;
                 } else
                         units_dir = *i;
 
-                if (d)
-                        closedir(d);
-
                 d = opendir(units_dir);
                 if (!d) {
                         if (errno == ENOENT)
@@ -1960,15 +1957,9 @@ int unit_file_get_list(
                         if (hashmap_get(h, de->d_name))
                                 continue;
 
-                        r = dirent_ensure_type(d, de);
-                        if (r < 0) {
-                                if (r == -ENOENT)
-                                        continue;
-
-                                return r;
-                        }
+                        dirent_ensure_type(d, de);
 
-                        if (de->d_type != DT_LNK && de->d_type != DT_REG)
+                        if (!IN_SET(de->d_type, DT_LNK, DT_REG))
                                 continue;
 
                         f = new0(UnitFileList, 1);