diff options
Diffstat (limited to 'src/core/unit.c')
-rw-r--r-- | src/core/unit.c | 61 |
1 files changed, 55 insertions, 6 deletions
diff --git a/src/core/unit.c b/src/core/unit.c index ac29353299..c028f57f13 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -52,6 +52,7 @@ #include "stdio-util.h" #include "string-util.h" #include "strv.h" +#include "umask-util.h" #include "unit-name.h" #include "unit.h" #include "user-util.h" @@ -492,6 +493,9 @@ void unit_free(Unit *u) { assert(u); + if (u->transient_file) + fclose(u->transient_file); + if (!MANAGER_IS_RELOADING(u->manager)) unit_remove_transient(u); @@ -1231,6 +1235,15 @@ int unit_load(Unit *u) { if (u->load_state != UNIT_STUB) return 0; + if (u->transient_file) { + r = fflush_and_check(u->transient_file); + if (r < 0) + goto fail; + + fclose(u->transient_file); + u->transient_file = NULL; + } + if (UNIT_VTABLE(u)->load) { r = UNIT_VTABLE(u)->load(u); if (r < 0) @@ -3327,14 +3340,17 @@ ExecRuntime *unit_get_exec_runtime(Unit *u) { static const char* unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode) { assert(u); + if (!IN_SET(mode, UNIT_RUNTIME, UNIT_PERSISTENT)) + return NULL; + if (u->transient) /* Redirect drop-ins for transient units always into the transient directory. */ return u->manager->lookup_paths.transient; if (mode == UNIT_RUNTIME) - return u->manager->lookup_paths.runtime_config; + return u->manager->lookup_paths.runtime_control; if (mode == UNIT_PERSISTENT) - return u->manager->lookup_paths.persistent_config; + return u->manager->lookup_paths.persistent_control; return NULL; } @@ -3346,6 +3362,13 @@ int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, co assert(u); + if (u->transient_file) { + /* When this is a transient unit file in creation, then let's not create a new drop-in but instead + * write to the transient unit file. */ + fputs(data, u->transient_file); + return 0; + } + if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME)) return 0; @@ -3435,24 +3458,50 @@ int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const } int unit_make_transient(Unit *u) { + FILE *f; + char *path; + assert(u); if (!UNIT_VTABLE(u)->can_transient) return -EOPNOTSUPP; - u->load_state = UNIT_STUB; - u->load_error = 0; - u->transient = true; + path = strjoin(u->manager->lookup_paths.transient, "/", u->id, NULL); + if (!path) + return -ENOMEM; + + /* Let's open the file we'll write the transient settings into. This file is kept open as long as we are + * creating the transient, and is closed in unit_load(), as soon as we start loading the file. */ + + RUN_WITH_UMASK(0022) + f = fopen(path, "we"); + if (!f) { + free(path); + return -errno; + } + + if (u->transient_file) + fclose(u->transient_file); + u->transient_file = f; + + free(u->fragment_path); + u->fragment_path = path; - u->fragment_path = mfree(u->fragment_path); u->source_path = mfree(u->source_path); u->dropin_paths = strv_free(u->dropin_paths); u->fragment_mtime = u->source_mtime = u->dropin_mtime = 0; + u->load_state = UNIT_STUB; + u->load_error = 0; + u->transient = true; + unit_add_to_dbus_queue(u); unit_add_to_gc_queue(u); unit_add_to_load_queue(u); + fputs("# This is a transient unit file, created programmatically via the systemd API. Do not edit.\n", + u->transient_file); + return 0; } |