diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/dbus-execute.c | 86 | ||||
-rw-r--r-- | src/core/dynamic-user.c | 4 | ||||
-rw-r--r-- | src/core/execute.c | 90 | ||||
-rw-r--r-- | src/core/execute.h | 5 | ||||
-rw-r--r-- | src/core/load-fragment-gperf.gperf.m4 | 6 | ||||
-rw-r--r-- | src/core/load-fragment.c | 114 | ||||
-rw-r--r-- | src/core/load-fragment.h | 2 | ||||
-rw-r--r-- | src/core/manager.c | 3 | ||||
-rw-r--r-- | src/core/mount.c | 14 | ||||
-rw-r--r-- | src/core/service.c | 4 | ||||
-rw-r--r-- | src/core/timer.c | 2 | ||||
-rw-r--r-- | src/core/transaction.c | 6 | ||||
-rw-r--r-- | src/core/unit.c | 46 |
13 files changed, 309 insertions, 73 deletions
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index b8720d7d3d..1a7f770db1 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -627,6 +627,53 @@ static int property_get_syslog_facility( return sd_bus_message_append(reply, "i", LOG_FAC(c->syslog_priority)); } +static int property_get_input_fdname( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + ExecContext *c = userdata; + const char *name; + + assert(bus); + assert(c); + assert(property); + assert(reply); + + name = exec_context_fdname(c, STDIN_FILENO); + + return sd_bus_message_append(reply, "s", name); +} + +static int property_get_output_fdname( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + ExecContext *c = userdata; + const char *name = NULL; + + assert(bus); + assert(c); + assert(property); + assert(reply); + + if (c->std_output == EXEC_OUTPUT_NAMED_FD && streq(property, "StandardOutputFileDescriptorName")) + name = exec_context_fdname(c, STDOUT_FILENO); + else if (c->std_error == EXEC_OUTPUT_NAMED_FD && streq(property, "StandardErrorFileDescriptorName")) + name = exec_context_fdname(c, STDERR_FILENO); + + return sd_bus_message_append(reply, "s", name); +} + const sd_bus_vtable bus_exec_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST), @@ -677,8 +724,11 @@ const sd_bus_vtable bus_exec_vtable[] = { SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input, offsetof(ExecContext, std_input), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("StandardInputFileDescriptorName", "s", property_get_input_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output, offsetof(ExecContext, std_output), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("StandardOutputFileDescriptorName", "s", property_get_output_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output, offsetof(ExecContext, std_error), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("StandardErrorFileDescriptorName", "s", property_get_output_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("TTYPath", "s", NULL, offsetof(ExecContext, tty_path), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), SD_BUS_VTABLE_PROPERTY_CONST), @@ -1030,7 +1080,6 @@ int bus_exec_context_set_transient_property( return 1; - } else if (streq(name, "StandardOutput")) { const char *s; ExecOutput p; @@ -1072,6 +1121,41 @@ int bus_exec_context_set_transient_property( return 1; } else if (STR_IN_SET(name, + "StandardInputFileDescriptorName", "StandardOutputFileDescriptorName", "StandardErrorFileDescriptorName")) { + const char *s; + + r = sd_bus_message_read(message, "s", &s); + if (r < 0) + return r; + + if (!fdname_is_valid(s)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid file descriptor name"); + + if (mode != UNIT_CHECK) { + if (streq(name, "StandardInputFileDescriptorName")) { + c->std_input = EXEC_INPUT_NAMED_FD; + r = free_and_strdup(&c->stdio_fdname[STDIN_FILENO], s); + if (r < 0) + return r; + unit_write_drop_in_private_format(u, mode, name, "StandardInput=fd:%s", s); + } else if (streq(name, "StandardOutputFileDescriptorName")) { + c->std_output = EXEC_OUTPUT_NAMED_FD; + r = free_and_strdup(&c->stdio_fdname[STDOUT_FILENO], s); + if (r < 0) + return r; + unit_write_drop_in_private_format(u, mode, name, "StandardOutput=fd:%s", s); + } else if (streq(name, "StandardErrorFileDescriptorName")) { + c->std_error = EXEC_OUTPUT_NAMED_FD; + r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], s); + if (r < 0) + return r; + unit_write_drop_in_private_format(u, mode, name, "StandardError=fd:%s", s); + } + } + + return 1; + + } else if (STR_IN_SET(name, "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "PrivateTmp", "PrivateDevices", "PrivateNetwork", "PrivateUsers", "NoNewPrivileges", "SyslogLevelPrefix", "MemoryDenyWriteExecute", diff --git a/src/core/dynamic-user.c b/src/core/dynamic-user.c index 1043da3eb7..e1846e1adb 100644 --- a/src/core/dynamic-user.c +++ b/src/core/dynamic-user.c @@ -42,9 +42,7 @@ static DynamicUser* dynamic_user_free(DynamicUser *d) { (void) hashmap_remove(d->manager->dynamic_users, d->name); safe_close_pair(d->storage_socket); - free(d); - - return NULL; + return mfree(d); } static int dynamic_user_add(Manager *m, const char *name, int storage_socket[2], DynamicUser **ret) { diff --git a/src/core/execute.c b/src/core/execute.c index 869522704a..1b7b4a928d 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -411,7 +411,8 @@ static int fixup_output(ExecOutput std_output, int socket_fd) { static int setup_input( const ExecContext *context, const ExecParameters *params, - int socket_fd) { + int socket_fd, + int named_iofds[3]) { ExecInput i; @@ -461,6 +462,10 @@ static int setup_input( case EXEC_INPUT_SOCKET: return dup2(socket_fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO; + case EXEC_INPUT_NAMED_FD: + (void) fd_nonblock(named_iofds[STDIN_FILENO], false); + return dup2(named_iofds[STDIN_FILENO], STDIN_FILENO) < 0 ? -errno : STDIN_FILENO; + default: assert_not_reached("Unknown input type"); } @@ -472,6 +477,7 @@ static int setup_output( const ExecParameters *params, int fileno, int socket_fd, + int named_iofds[3], const char *ident, uid_t uid, gid_t gid, @@ -523,7 +529,7 @@ static int setup_output( return fileno; /* Duplicate from stdout if possible */ - if (e == o || e == EXEC_OUTPUT_INHERIT) + if ((e == o && e != EXEC_OUTPUT_NAMED_FD) || e == EXEC_OUTPUT_INHERIT) return dup2(STDOUT_FILENO, fileno) < 0 ? -errno : fileno; o = e; @@ -585,6 +591,10 @@ static int setup_output( assert(socket_fd >= 0); return dup2(socket_fd, fileno) < 0 ? -errno : fileno; + case EXEC_OUTPUT_NAMED_FD: + (void) fd_nonblock(named_iofds[fileno], false); + return dup2(named_iofds[fileno], fileno) < 0 ? -errno : fileno; + default: assert_not_reached("Unknown error type"); } @@ -2157,6 +2167,7 @@ static int exec_child( DynamicCreds *dcreds, char **argv, int socket_fd, + int named_iofds[3], int *fds, unsigned n_fds, char **files_env, int user_lookup_fd, @@ -2298,19 +2309,19 @@ static int exec_child( if (socket_fd >= 0) (void) fd_nonblock(socket_fd, false); - r = setup_input(context, params, socket_fd); + r = setup_input(context, params, socket_fd, named_iofds); if (r < 0) { *exit_status = EXIT_STDIN; return r; } - r = setup_output(unit, context, params, STDOUT_FILENO, socket_fd, basename(command->path), uid, gid, &journal_stream_dev, &journal_stream_ino); + r = setup_output(unit, context, params, STDOUT_FILENO, socket_fd, named_iofds, basename(command->path), uid, gid, &journal_stream_dev, &journal_stream_ino); if (r < 0) { *exit_status = EXIT_STDOUT; return r; } - r = setup_output(unit, context, params, STDERR_FILENO, socket_fd, basename(command->path), uid, gid, &journal_stream_dev, &journal_stream_ino); + r = setup_output(unit, context, params, STDERR_FILENO, socket_fd, named_iofds, basename(command->path), uid, gid, &journal_stream_dev, &journal_stream_ino); if (r < 0) { *exit_status = EXIT_STDERR; return r; @@ -2829,6 +2840,7 @@ int exec_spawn(Unit *unit, int *fds = NULL; unsigned n_fds = 0; _cleanup_free_ char *line = NULL; int socket_fd, r; + int named_iofds[3] = { -1, -1, -1 }; char **argv; pid_t pid; @@ -2855,6 +2867,10 @@ int exec_spawn(Unit *unit, n_fds = params->n_fds; } + r = exec_context_named_iofds(unit, context, params, named_iofds); + if (r < 0) + return log_unit_error_errno(unit, r, "Failed to load a named file descriptor: %m"); + r = exec_context_load_environment(unit, context, &files_env); if (r < 0) return log_unit_error_errno(unit, r, "Failed to load environment files: %m"); @@ -2884,6 +2900,7 @@ int exec_spawn(Unit *unit, dcreds, argv, socket_fd, + named_iofds, fds, n_fds, files_env, unit->manager->user_lookup_fds[1], @@ -2946,6 +2963,9 @@ void exec_context_done(ExecContext *c) { for (l = 0; l < ELEMENTSOF(c->rlimit); l++) c->rlimit[l] = mfree(c->rlimit[l]); + for (l = 0; l < 3; l++) + c->stdio_fdname[l] = mfree(c->stdio_fdname[l]); + c->working_directory = mfree(c->working_directory); c->root_directory = mfree(c->root_directory); c->tty_path = mfree(c->tty_path); @@ -3044,6 +3064,56 @@ static void invalid_env(const char *p, void *userdata) { log_unit_error(info->unit, "Ignoring invalid environment assignment '%s': %s", p, info->path); } +const char* exec_context_fdname(const ExecContext *c, int fd_index) { + assert(c); + + switch (fd_index) { + case STDIN_FILENO: + if (c->std_input != EXEC_INPUT_NAMED_FD) + return NULL; + return c->stdio_fdname[STDIN_FILENO] ?: "stdin"; + case STDOUT_FILENO: + if (c->std_output != EXEC_OUTPUT_NAMED_FD) + return NULL; + return c->stdio_fdname[STDOUT_FILENO] ?: "stdout"; + case STDERR_FILENO: + if (c->std_error != EXEC_OUTPUT_NAMED_FD) + return NULL; + return c->stdio_fdname[STDERR_FILENO] ?: "stderr"; + default: + return NULL; + } +} + +int exec_context_named_iofds(Unit *unit, const ExecContext *c, const ExecParameters *p, int named_iofds[3]) { + unsigned i, targets; + const char *stdio_fdname[3]; + + assert(c); + assert(p); + + targets = (c->std_input == EXEC_INPUT_NAMED_FD) + + (c->std_output == EXEC_OUTPUT_NAMED_FD) + + (c->std_error == EXEC_OUTPUT_NAMED_FD); + + for (i = 0; i < 3; i++) + stdio_fdname[i] = exec_context_fdname(c, i); + + for (i = 0; i < p->n_fds && targets > 0; i++) + if (named_iofds[STDIN_FILENO] < 0 && c->std_input == EXEC_INPUT_NAMED_FD && stdio_fdname[STDIN_FILENO] && streq(p->fd_names[i], stdio_fdname[STDIN_FILENO])) { + named_iofds[STDIN_FILENO] = p->fds[i]; + targets--; + } else if (named_iofds[STDOUT_FILENO] < 0 && c->std_output == EXEC_OUTPUT_NAMED_FD && stdio_fdname[STDOUT_FILENO] && streq(p->fd_names[i], stdio_fdname[STDOUT_FILENO])) { + named_iofds[STDOUT_FILENO] = p->fds[i]; + targets--; + } else if (named_iofds[STDERR_FILENO] < 0 && c->std_error == EXEC_OUTPUT_NAMED_FD && stdio_fdname[STDERR_FILENO] && streq(p->fd_names[i], stdio_fdname[STDERR_FILENO])) { + named_iofds[STDERR_FILENO] = p->fds[i]; + targets--; + } + + return (targets == 0 ? 0 : -ENOENT); +} + int exec_context_load_environment(Unit *unit, const ExecContext *c, char ***l) { char **i, **r = NULL; @@ -3740,9 +3810,7 @@ ExecRuntime *exec_runtime_unref(ExecRuntime *r) { free(r->tmp_dir); free(r->var_tmp_dir); safe_close_pair(r->netns_storage_socket); - free(r); - - return NULL; + return mfree(r); } int exec_runtime_serialize(Unit *u, ExecRuntime *rt, FILE *f, FDSet *fds) { @@ -3898,7 +3966,8 @@ static const char* const exec_input_table[_EXEC_INPUT_MAX] = { [EXEC_INPUT_TTY] = "tty", [EXEC_INPUT_TTY_FORCE] = "tty-force", [EXEC_INPUT_TTY_FAIL] = "tty-fail", - [EXEC_INPUT_SOCKET] = "socket" + [EXEC_INPUT_SOCKET] = "socket", + [EXEC_INPUT_NAMED_FD] = "fd", }; DEFINE_STRING_TABLE_LOOKUP(exec_input, ExecInput); @@ -3913,7 +3982,8 @@ static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = { [EXEC_OUTPUT_KMSG_AND_CONSOLE] = "kmsg+console", [EXEC_OUTPUT_JOURNAL] = "journal", [EXEC_OUTPUT_JOURNAL_AND_CONSOLE] = "journal+console", - [EXEC_OUTPUT_SOCKET] = "socket" + [EXEC_OUTPUT_SOCKET] = "socket", + [EXEC_OUTPUT_NAMED_FD] = "fd", }; DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput); diff --git a/src/core/execute.h b/src/core/execute.h index 1de439c3ad..c7d0f7761e 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -50,6 +50,7 @@ typedef enum ExecInput { EXEC_INPUT_TTY_FORCE, EXEC_INPUT_TTY_FAIL, EXEC_INPUT_SOCKET, + EXEC_INPUT_NAMED_FD, _EXEC_INPUT_MAX, _EXEC_INPUT_INVALID = -1 } ExecInput; @@ -65,6 +66,7 @@ typedef enum ExecOutput { EXEC_OUTPUT_JOURNAL, EXEC_OUTPUT_JOURNAL_AND_CONSOLE, EXEC_OUTPUT_SOCKET, + EXEC_OUTPUT_NAMED_FD, _EXEC_OUTPUT_MAX, _EXEC_OUTPUT_INVALID = -1 } ExecOutput; @@ -120,6 +122,7 @@ struct ExecContext { ExecInput std_input; ExecOutput std_output; ExecOutput std_error; + char *stdio_fdname[3]; nsec_t timer_slack_nsec; @@ -284,6 +287,8 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix); int exec_context_destroy_runtime_directory(ExecContext *c, const char *runtime_root); int exec_context_load_environment(Unit *unit, const ExecContext *c, char ***l); +int exec_context_named_iofds(Unit *unit, const ExecContext *c, const ExecParameters *p, int named_iofds[3]); +const char* exec_context_fdname(const ExecContext *c, int fd_index); bool exec_context_may_touch_console(ExecContext *c); bool exec_context_maintains_privileges(ExecContext *c); diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index a700d853cc..08c88b6b53 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -35,9 +35,9 @@ $1.Environment, config_parse_environ, 0, $1.EnvironmentFile, config_parse_unit_env_file, 0, offsetof($1, exec_context.environment_files) $1.PassEnvironment, config_parse_pass_environ, 0, offsetof($1, exec_context.pass_environment) $1.DynamicUser, config_parse_bool, 0, offsetof($1, exec_context.dynamic_user) -$1.StandardInput, config_parse_input, 0, offsetof($1, exec_context.std_input) -$1.StandardOutput, config_parse_output, 0, offsetof($1, exec_context.std_output) -$1.StandardError, config_parse_output, 0, offsetof($1, exec_context.std_error) +$1.StandardInput, config_parse_exec_input, 0, offsetof($1, exec_context) +$1.StandardOutput, config_parse_exec_output, 0, offsetof($1, exec_context) +$1.StandardError, config_parse_exec_output, 0, offsetof($1, exec_context) $1.TTYPath, config_parse_unit_path_printf, 0, offsetof($1, exec_context.tty_path) $1.TTYReset, config_parse_bool, 0, offsetof($1, exec_context.tty_reset) $1.TTYVHangup, config_parse_bool, 0, offsetof($1, exec_context.tty_vhangup) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 06c156a623..a69f60097d 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -776,8 +776,104 @@ int config_parse_socket_bindtodevice( return 0; } -DEFINE_CONFIG_PARSE_ENUM(config_parse_output, exec_output, ExecOutput, "Failed to parse output specifier"); -DEFINE_CONFIG_PARSE_ENUM(config_parse_input, exec_input, ExecInput, "Failed to parse input specifier"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_input, exec_input, ExecInput, "Failed to parse input literal specifier"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_output, exec_output, ExecOutput, "Failed to parse output literal specifier"); + +int config_parse_exec_input(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + ExecContext *c = data; + const char *name; + int r; + + assert(data); + assert(filename); + assert(line); + assert(rvalue); + + name = startswith(rvalue, "fd:"); + if (name) { + /* Strip prefix and validate fd name */ + if (!fdname_is_valid(name)) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid file descriptor name, ignoring: %s", name); + return 0; + } + c->std_input = EXEC_INPUT_NAMED_FD; + r = free_and_strdup(&c->stdio_fdname[STDIN_FILENO], name); + if (r < 0) + log_oom(); + return r; + } else { + ExecInput ei = exec_input_from_string(rvalue); + if (ei == _EXEC_INPUT_INVALID) + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse input specifier, ignoring: %s", rvalue); + else + c->std_input = ei; + return 0; + } +} + +int config_parse_exec_output(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + ExecContext *c = data; + ExecOutput eo; + const char *name; + int r; + + assert(data); + assert(filename); + assert(line); + assert(lvalue); + assert(rvalue); + + name = startswith(rvalue, "fd:"); + if (name) { + /* Strip prefix and validate fd name */ + if (!fdname_is_valid(name)) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid file descriptor name, ignoring: %s", name); + return 0; + } + eo = EXEC_OUTPUT_NAMED_FD; + } else { + eo = exec_output_from_string(rvalue); + if (eo == _EXEC_OUTPUT_INVALID) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse output specifier, ignoring: %s", rvalue); + return 0; + } + } + + if (streq(lvalue, "StandardOutput")) { + c->std_output = eo; + r = free_and_strdup(&c->stdio_fdname[STDOUT_FILENO], name); + if (r < 0) + log_oom(); + return r; + } else if (streq(lvalue, "StandardError")) { + c->std_error = eo; + r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], name); + if (r < 0) + log_oom(); + return r; + } else { + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse output property, ignoring: %s", lvalue); + return 0; + } +} int config_parse_exec_io_class(const char *unit, const char *filename, @@ -1591,11 +1687,7 @@ int config_parse_fdname( return 0; } - free(s->fdname); - s->fdname = p; - p = NULL; - - return 0; + return free_and_replace(s->fdname, p); } int config_parse_service_sockets( @@ -2052,9 +2144,7 @@ int config_parse_working_directory( return 0; } - free(c->working_directory); - c->working_directory = k; - k = NULL; + free_and_replace(c->working_directory, k); c->working_directory_home = false; } @@ -4189,8 +4279,8 @@ void unit_dump_config_items(FILE *f) { { config_parse_exec_cpu_affinity, "CPUAFFINITY" }, { config_parse_mode, "MODE" }, { config_parse_unit_env_file, "FILE" }, - { config_parse_output, "OUTPUT" }, - { config_parse_input, "INPUT" }, + { config_parse_exec_output, "OUTPUT" }, + { config_parse_exec_input, "INPUT" }, { config_parse_log_facility, "FACILITY" }, { config_parse_log_level, "LEVEL" }, { config_parse_exec_secure_bits, "SECUREBITS" }, diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h index 8b688740cf..6d1fe55bcd 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -45,7 +45,9 @@ int config_parse_service_timeout(const char *unit, const char *filename, unsigne int config_parse_service_type(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_service_restart(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_socket_bindtodevice(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_output(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_output(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_input(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_input(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_exec_io_class(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_exec_io_priority(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); diff --git a/src/core/manager.c b/src/core/manager.c index 3569249788..50aae0d1ba 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -1119,8 +1119,7 @@ Manager* manager_free(Manager *m) { hashmap_free(m->uid_refs); hashmap_free(m->gid_refs); - free(m); - return NULL; + return mfree(m); } void manager_enumerate(Manager *m) { diff --git a/src/core/mount.c b/src/core/mount.c index 15619dffe3..da480001e1 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -1484,17 +1484,9 @@ static int mount_setup_unit( MOUNT(u)->from_proc_self_mountinfo = true; - free(p->what); - p->what = w; - w = NULL; - - free(p->options); - p->options = o; - o = NULL; - - free(p->fstype); - p->fstype = f; - f = NULL; + free_and_replace(p->what, w); + free_and_replace(p->options, o); + free_and_replace(p->fstype, f); if (load_extras) { r = mount_add_extras(MOUNT(u)); diff --git a/src/core/service.c b/src/core/service.c index 63045ede55..c949de9cbe 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -3088,9 +3088,7 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds) if (!streq_ptr(s->status_text, t)) { - free(s->status_text); - s->status_text = t; - t = NULL; + free_and_replace(s->status_text, t); notify_dbus = true; } diff --git a/src/core/timer.c b/src/core/timer.c index 9538059c13..2469a517ea 100644 --- a/src/core/timer.c +++ b/src/core/timer.c @@ -261,6 +261,8 @@ static void timer_set_state(Timer *t, TimerState state) { if (state != TIMER_WAITING) { t->monotonic_event_source = sd_event_source_unref(t->monotonic_event_source); t->realtime_event_source = sd_event_source_unref(t->realtime_event_source); + t->next_elapse_monotonic_or_boottime = USEC_INFINITY; + t->next_elapse_realtime = USEC_INFINITY; } if (state != old_state) diff --git a/src/core/transaction.c b/src/core/transaction.c index 8370b864fb..e22e3b30c2 100644 --- a/src/core/transaction.c +++ b/src/core/transaction.c @@ -1085,10 +1085,8 @@ Transaction *transaction_new(bool irreversible) { return NULL; tr->jobs = hashmap_new(NULL); - if (!tr->jobs) { - free(tr); - return NULL; - } + if (!tr->jobs) + return mfree(tr); tr->irreversible = irreversible; diff --git a/src/core/unit.c b/src/core/unit.c index 67668bdc48..2fa397bd41 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -88,10 +88,8 @@ Unit *unit_new(Manager *m, size_t size) { return NULL; u->names = set_new(&string_hash_ops); - if (!u->names) { - free(u); - return NULL; - } + if (!u->names) + return mfree(u); u->manager = m; u->type = _UNIT_TYPE_INVALID; @@ -860,18 +858,14 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) { return r; } - if (c->std_output != EXEC_OUTPUT_KMSG && - c->std_output != EXEC_OUTPUT_SYSLOG && - c->std_output != EXEC_OUTPUT_JOURNAL && - c->std_output != EXEC_OUTPUT_KMSG_AND_CONSOLE && - c->std_output != EXEC_OUTPUT_SYSLOG_AND_CONSOLE && - c->std_output != EXEC_OUTPUT_JOURNAL_AND_CONSOLE && - c->std_error != EXEC_OUTPUT_KMSG && - c->std_error != EXEC_OUTPUT_SYSLOG && - c->std_error != EXEC_OUTPUT_JOURNAL && - c->std_error != EXEC_OUTPUT_KMSG_AND_CONSOLE && - c->std_error != EXEC_OUTPUT_JOURNAL_AND_CONSOLE && - c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE) + if (!IN_SET(c->std_output, + EXEC_OUTPUT_JOURNAL, EXEC_OUTPUT_JOURNAL_AND_CONSOLE, + EXEC_OUTPUT_KMSG, EXEC_OUTPUT_KMSG_AND_CONSOLE, + EXEC_OUTPUT_SYSLOG, EXEC_OUTPUT_SYSLOG_AND_CONSOLE) && + !IN_SET(c->std_error, + EXEC_OUTPUT_JOURNAL, EXEC_OUTPUT_JOURNAL_AND_CONSOLE, + EXEC_OUTPUT_KMSG, EXEC_OUTPUT_KMSG_AND_CONSOLE, + EXEC_OUTPUT_SYSLOG, EXEC_OUTPUT_SYSLOG_AND_CONSOLE)) return 0; /* If syslog or kernel logging is requested, make sure our own @@ -3055,7 +3049,7 @@ int unit_coldplug(Unit *u) { return r; } -static bool fragment_mtime_newer(const char *path, usec_t mtime) { +static bool fragment_mtime_newer(const char *path, usec_t mtime, bool path_masked) { struct stat st; if (!path) @@ -3065,12 +3059,12 @@ static bool fragment_mtime_newer(const char *path, usec_t mtime) { /* What, cannot access this anymore? */ return true; - if (mtime > 0) + if (path_masked) + /* For masked files check if they are still so */ + return !null_or_empty(&st); + else /* For non-empty files check the mtime */ return timespec_load(&st.st_mtim) > mtime; - else if (!null_or_empty(&st)) - /* For masked files check if they are still so */ - return true; return false; } @@ -3081,18 +3075,22 @@ bool unit_need_daemon_reload(Unit *u) { assert(u); - if (fragment_mtime_newer(u->fragment_path, u->fragment_mtime)) + /* For unit files, we allow masking… */ + if (fragment_mtime_newer(u->fragment_path, u->fragment_mtime, + u->load_state == UNIT_MASKED)) return true; - if (fragment_mtime_newer(u->source_path, u->source_mtime)) + /* Source paths should not be masked… */ + if (fragment_mtime_newer(u->source_path, u->source_mtime, false)) return true; (void) unit_find_dropin_paths(u, &t); if (!strv_equal(u->dropin_paths, t)) return true; + /* … any drop-ins that are masked are simply omitted from the list. */ STRV_FOREACH(path, u->dropin_paths) - if (fragment_mtime_newer(*path, u->dropin_mtime)) + if (fragment_mtime_newer(*path, u->dropin_mtime, false)) return true; return false; |