diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/dbus-execute.c | 115 | ||||
-rw-r--r-- | src/core/dbus-execute.h | 1 | ||||
-rw-r--r-- | src/core/dbus-service.c | 110 | ||||
-rw-r--r-- | src/core/dbus-socket.c | 486 | ||||
-rw-r--r-- | src/core/socket.c | 2 |
5 files changed, 605 insertions, 109 deletions
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 4b1160cab4..f0282f7750 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -1036,6 +1036,121 @@ int bus_property_get_exec_command_list( return sd_bus_message_close_container(reply); } +int bus_exec_command_set_transient_property( + Unit *u, + const char *name, + ExecCommand **exec_command, + sd_bus_message *message, + UnitWriteFlags flags, + sd_bus_error *error) { + unsigned n = 0; + int r; + + r = sd_bus_message_enter_container(message, 'a', "(sasb)"); + if (r < 0) + return r; + + while ((r = sd_bus_message_enter_container(message, 'r', "sasb")) > 0) { + _cleanup_strv_free_ char **argv = NULL; + const char *path; + int b; + + r = sd_bus_message_read(message, "s", &path); + if (r < 0) + return r; + + if (!path_is_absolute(path)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path); + + r = sd_bus_message_read_strv(message, &argv); + if (r < 0) + return r; + + r = sd_bus_message_read(message, "b", &b); + if (r < 0) + return r; + + r = sd_bus_message_exit_container(message); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + ExecCommand *c; + + c = new0(ExecCommand, 1); + if (!c) + return -ENOMEM; + + c->path = strdup(path); + if (!c->path) { + free(c); + return -ENOMEM; + } + + c->argv = argv; + argv = NULL; + + c->flags = b ? EXEC_COMMAND_IGNORE_FAILURE : 0; + + path_kill_slashes(c->path); + exec_command_append_list(exec_command, c); + } + + n++; + } + if (r < 0) + return r; + + r = sd_bus_message_exit_container(message); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + _cleanup_free_ char *buf = NULL; + _cleanup_fclose_ FILE *f = NULL; + ExecCommand *c; + size_t size = 0; + + if (n == 0) + *exec_command = exec_command_free_list(*exec_command); + + f = open_memstream(&buf, &size); + if (!f) + return -ENOMEM; + + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + + fputs("ExecStart=\n", f); + + LIST_FOREACH(command, c, *exec_command) { + _cleanup_free_ char *a = NULL, *t = NULL; + const char *p; + + p = unit_escape_setting(c->path, UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS, &t); + if (!p) + return -ENOMEM; + + a = unit_concat_strv(c->argv, UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS); + if (!a) + return -ENOMEM; + + fprintf(f, "%s=%s@%s %s\n", + name, + c->flags & EXEC_COMMAND_IGNORE_FAILURE ? "-" : "", + p, + a); + } + + r = fflush_and_check(f); + if (r < 0) + return r; + + unit_write_setting(u, flags, name, buf); + } + + return 1; +} + int bus_exec_context_set_transient_property( Unit *u, ExecContext *c, diff --git a/src/core/dbus-execute.h b/src/core/dbus-execute.h index f30f0774cd..3654598f4b 100644 --- a/src/core/dbus-execute.h +++ b/src/core/dbus-execute.h @@ -44,3 +44,4 @@ int bus_property_get_exec_command(sd_bus *bus, const char *path, const char *int int bus_property_get_exec_command_list(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error); int bus_exec_context_set_transient_property(Unit *u, ExecContext *c, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); +int bus_exec_command_set_transient_property(Unit *u, const char *name, ExecCommand **exec_command, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index 0189952124..c5eba5f4e5 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -239,114 +239,8 @@ static int bus_service_set_transient_property( return 1; - } else if ((ci = service_exec_command_from_string(name)) >= 0) { - unsigned n = 0; - - r = sd_bus_message_enter_container(message, 'a', "(sasb)"); - if (r < 0) - return r; - - while ((r = sd_bus_message_enter_container(message, 'r', "sasb")) > 0) { - _cleanup_strv_free_ char **argv = NULL; - const char *path; - int b; - - r = sd_bus_message_read(message, "s", &path); - if (r < 0) - return r; - - if (!path_is_absolute(path)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path); - - r = sd_bus_message_read_strv(message, &argv); - if (r < 0) - return r; - - r = sd_bus_message_read(message, "b", &b); - if (r < 0) - return r; - - r = sd_bus_message_exit_container(message); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - ExecCommand *c; - - c = new0(ExecCommand, 1); - if (!c) - return -ENOMEM; - - c->path = strdup(path); - if (!c->path) { - free(c); - return -ENOMEM; - } - - c->argv = argv; - argv = NULL; - - c->flags = b ? EXEC_COMMAND_IGNORE_FAILURE : 0; - - path_kill_slashes(c->path); - exec_command_append_list(&s->exec_command[ci], c); - } - - n++; - } - - if (r < 0) - return r; - - r = sd_bus_message_exit_container(message); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - _cleanup_free_ char *buf = NULL; - _cleanup_fclose_ FILE *f = NULL; - ExecCommand *c; - size_t size = 0; - - if (n == 0) - s->exec_command[ci] = exec_command_free_list(s->exec_command[ci]); - - f = open_memstream(&buf, &size); - if (!f) - return -ENOMEM; - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); - - fputs("ExecStart=\n", f); - - LIST_FOREACH(command, c, s->exec_command[ci]) { - _cleanup_free_ char *a = NULL, *t = NULL; - const char *p; - - p = unit_escape_setting(c->path, UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS, &t); - if (!p) - return -ENOMEM; - - a = unit_concat_strv(c->argv, UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS); - if (!a) - return -ENOMEM; - - fprintf(f, "%s=%s@%s %s\n", - name, - c->flags & EXEC_COMMAND_IGNORE_FAILURE ? "-" : "", - p, - a); - } - - r = fflush_and_check(f); - if (r < 0) - return r; - - unit_write_setting(UNIT(s), flags, name, buf); - } - - return 1; - } + } else if ((ci = service_exec_command_from_string(name)) >= 0) + return bus_exec_command_set_transient_property(UNIT(s), name, &s->exec_command[ci], message, flags, error); return 0; } diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c index 930b7fa87d..6c5d5944fc 100644 --- a/src/core/dbus-socket.c +++ b/src/core/dbus-socket.c @@ -22,10 +22,17 @@ #include "bus-util.h" #include "dbus-cgroup.h" #include "dbus-execute.h" +#include "dbus-kill.h" #include "dbus-socket.h" +#include "fd-util.h" +#include "parse-util.h" +#include "path-util.h" #include "socket.h" +#include "socket-util.h" #include "string-util.h" #include "unit.h" +#include "user-util.h" +#include "utf8.h" static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, socket_result, SocketResult); static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_bind_ipv6_only, socket_address_bind_ipv6_only, SocketAddressBindIPv6Only); @@ -141,6 +148,7 @@ const sd_bus_vtable bus_socket_vtable[] = { SD_BUS_PROPERTY("MaxConnectionsPerSource", "u", bus_property_get_unsigned, offsetof(Socket, max_connections_per_source), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("MessageQueueMaxMessages", "x", bus_property_get_long, offsetof(Socket, mq_maxmsg), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("MessageQueueMessageSize", "x", bus_property_get_long, offsetof(Socket, mq_msgsize), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("TCPCongestion", "s", NULL, offsetof(Socket, tcp_congestion), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("ReusePort", "b", bus_property_get_bool, offsetof(Socket, reuse_port), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("SmackLabel", "s", NULL, offsetof(Socket, smack), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("SmackLabelIPIn", "s", NULL, offsetof(Socket, smack_ip_in), SD_BUS_VTABLE_PROPERTY_CONST), @@ -162,6 +170,457 @@ const sd_bus_vtable bus_socket_vtable[] = { SD_BUS_VTABLE_END }; +static int bus_socket_set_transient_property( + Socket *s, + const char *name, + sd_bus_message *message, + UnitWriteFlags flags, + sd_bus_error *error) { + + SocketExecCommand ci; + Unit *u = UNIT(s); + int r; + + assert(s); + assert(name); + assert(message); + + flags |= UNIT_PRIVATE; + + if (STR_IN_SET(name, + "Accept", "Writable", "KeepAlive", "NoDelay", "FreeBind", "Transparent", "Broadcast", + "PassCredentials", "PassSecurity", "ReusePort", "RemoveOnStop", "SELinuxContextFromNet")) { + int b; + + r = sd_bus_message_read(message, "b", &b); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + if (streq(name, "Accept")) + s->accept = b; + else if (streq(name, "Writable")) + s->writable = b; + else if (streq(name, "KeepAlive")) + s->keep_alive = b; + else if (streq(name, "NoDelay")) + s->no_delay = b; + else if (streq(name, "FreeBind")) + s->free_bind = b; + else if (streq(name, "Transparent")) + s->transparent = b; + else if (streq(name, "Broadcast")) + s->broadcast = b; + else if (streq(name, "PassCredentials")) + s->pass_cred = b; + else if (streq(name, "PassSecurity")) + s->pass_sec = b; + else if (streq(name, "ReusePort")) + s->reuse_port = b; + else if (streq(name, "RemoveOnStop")) + s->remove_on_stop = b; + else /* "SELinuxContextFromNet" */ + s->selinux_context_from_net = b; + + unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(b)); + } + + return 1; + + } else if (STR_IN_SET(name, "Priority", "IPTTL", "Mark")) { + int32_t i; + + r = sd_bus_message_read(message, "i", &i); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + if (streq(name, "Priority")) + s->priority = i; + else if (streq(name, "IPTTL")) + s->ip_ttl = i; + else /* "Mark" */ + s->mark = i; + + unit_write_settingf(u, flags, name, "%s=%i", name, i); + } + + return 1; + + } else if (streq(name, "IPTOS")) { + _cleanup_free_ char *str = NULL; + int32_t i; + + r = sd_bus_message_read(message, "i", &i); + if (r < 0) + return r; + + r = ip_tos_to_string_alloc(i, &str); + if (r < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s: %i", name, i); + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + s->ip_tos = i; + + unit_write_settingf(u, flags, name, "%s=%s", name, str); + } + + return 1; + + } else if (streq(name, "SocketProtocol")) { + int32_t i; + + r = sd_bus_message_read(message, "i", &i); + if (r < 0) + return r; + + if (!IN_SET(i, IPPROTO_UDPLITE, IPPROTO_SCTP)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s: %i", name, i); + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + s->socket_protocol = i; + unit_write_settingf(u, flags, name, "%s=%s", name, i == IPPROTO_UDPLITE ? "udplite" : "sctp"); + } + + return 1; + + } else if (STR_IN_SET(name, "Backlog", "MaxConnections", "MaxConnectionsPerSource", "KeepAliveProbes", "TriggerLimitBurst")) { + uint32_t n; + + r = sd_bus_message_read(message, "u", &n); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + if (streq(name, "Backlog")) + s->backlog = n; + else if (streq(name, "MaxConnections")) + s->max_connections = n; + else if (streq(name, "MaxConnectionsPerSource")) + s->max_connections_per_source = n; + else if (streq(name, "KeepAliveProbes")) + s->keep_alive_cnt = n; + else /* "TriggerLimitBurst" */ + s->trigger_limit.burst = n; + + unit_write_settingf(u, flags, name, "%s=%u", name, n); + } + + return 1; + + } else if (STR_IN_SET(name, "SocketMode", "DirectoryMode")) { + mode_t m; + + r = sd_bus_message_read(message, "u", &m); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + if (streq(name, "SocketMode")) + s->socket_mode = m; + else /* "DirectoryMode" */ + s->directory_mode = m; + + unit_write_settingf(u, flags, name, "%s=%040o", name, m); + } + + return 1; + + } else if (STR_IN_SET(name, "MessageQueueMaxMessages", "MessageQueueMessageSize")) { + int64_t n; + + r = sd_bus_message_read(message, "x", &n); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + if (streq(name, "MessageQueueMaxMessages")) + s->mq_maxmsg = (long) n; + else /* "MessageQueueMessageSize" */ + s->mq_msgsize = (long) n; + + unit_write_settingf(u, flags, name, "%s=%" PRIi64, name, n); + } + + return 1; + + } else if (STR_IN_SET(name, "TimeoutUSec", "KeepAliveTimeUSec", "KeepAliveIntervalUSec", "DeferAcceptUSec", "TriggerLimitIntervalUSec")) { + usec_t t; + + r = sd_bus_message_read(message, "t", &t); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + if (streq(name, "TimeoutUSec")) + s->timeout_usec = t ?: USEC_INFINITY; + else if (streq(name, "KeepAliveTimeUSec")) + s->keep_alive_time = t; + else if (streq(name, "KeepAliveIntervalUSec")) + s->keep_alive_interval = t; + else if (streq(name, "DeferAcceptUSec")) + s->defer_accept = t; + else /* "TriggerLimitIntervalUSec" */ + s->trigger_limit.interval = t; + + unit_write_settingf(u, flags, name, "%s=" USEC_FMT, name, t); + } + + return 1; + + } else if (STR_IN_SET(name, "ReceiveBuffer", "SendBuffer", "PipeSize")) { + uint64_t t; + + r = sd_bus_message_read(message, "t", &t); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + if (streq(name, "ReceiveBuffer")) + s->receive_buffer = t; + else if (streq(name, "SendBuffer")) + s->send_buffer = t; + else /* "PipeSize" */ + s->pipe_size = t; + + unit_write_settingf(u, flags, name, "%s=%" PRIu64, name, t); + } + + return 1; + + } else if (STR_IN_SET(name, "SmackLabel", "SmackLabelIPIn", "SmackLabelIPOut", "TCPCongestion")) { + const char *n; + + r = sd_bus_message_read(message, "s", &n); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + + if (streq(name, "SmackLabel")) + r = free_and_strdup(&s->smack, empty_to_null(n)); + else if (streq(name, "SmackLabelIPin")) + r = free_and_strdup(&s->smack_ip_in, empty_to_null(n)); + else if (streq(name, "SmackLabelIPOut")) + r = free_and_strdup(&s->smack_ip_out, empty_to_null(n)); + else /* "TCPCongestion" */ + r = free_and_strdup(&s->tcp_congestion, empty_to_null(n)); + if (r < 0) + return r; + + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, strempty(n)); + } + + return 1; + + } else if (streq(name, "BindToDevice")) { + const char *n; + + r = sd_bus_message_read(message, "s", &n); + if (r < 0) + return r; + + if (n[0] && !streq(n, "*")) { + if (!ifname_valid(n)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface name for %s: %s", name, n); + } else + n = NULL; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + + r = free_and_strdup(&s->bind_to_device, empty_to_null(n)); + if (r < 0) + return r; + + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, strempty(n)); + } + + return 1; + + } else if (streq(name, "BindIPv6Only")) { + SocketAddressBindIPv6Only b; + const char *n; + + r = sd_bus_message_read(message, "s", &n); + if (r < 0) + return r; + + b = socket_address_bind_ipv6_only_from_string(n); + if (b < 0) { + r = parse_boolean(n); + if (r < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s: %s", name, n); + + b = r ? SOCKET_ADDRESS_IPV6_ONLY : SOCKET_ADDRESS_BOTH; + } + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + s->bind_ipv6_only = b; + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, n); + } + + return 1; + + } else if (streq(name, "FileDescriptorName")) { + const char *n; + + r = sd_bus_message_read(message, "s", &n); + if (r < 0) + return r; + + if (!isempty(n) && !fdname_is_valid(n)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s: %s", name, n); + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + r = free_and_strdup(&s->fdname, empty_to_null(n)); + if (r < 0) + return r; + + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, strempty(n)); + } + + return 1; + + } else if (STR_IN_SET(name, "SocketUser", "SocketGroup")) { + const char *n; + + r = sd_bus_message_read(message, "s", &n); + if (r < 0) + return r; + + if (!isempty(n) && !valid_user_group_name_or_id(n)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s: %s", name, n); + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + + if (streq(name, "SocketUser")) + r = free_and_strdup(&s->user, empty_to_null(n)); + else /* "SocketGroup" */ + r = free_and_strdup(&s->user, empty_to_null(n)); + if (r < 0) + return r; + + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, strempty(n)); + } + + return 1; + + } else if (streq(name, "Symlinks")) { + _cleanup_strv_free_ char **l = NULL; + char **p; + + r = sd_bus_message_read_strv(message, &l); + if (r < 0) + return r; + + STRV_FOREACH(p, l) { + if (!utf8_is_valid(*p)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "String is not UTF-8 clean, ignoring assignment: %s", *p); + + if (!path_is_absolute(*p)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Symlink path is not absolute: %s", *p); + } + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + if (strv_isempty(l)) { + s->symlinks = strv_free(s->symlinks); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=", name); + } else { + _cleanup_free_ char *joined = NULL; + + r = strv_extend_strv(&s->symlinks, l, true); + if (r < 0) + return -ENOMEM; + + joined = strv_join(l, " "); + if (!joined) + return -ENOMEM; + + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, joined); + } + } + + return 1; + + } else if (streq(name, "Listen")) { + const char *t, *a; + bool empty = true; + + r = sd_bus_message_enter_container(message, 'a', "(ss)"); + if (r < 0) + return r; + + while ((r = sd_bus_message_read(message, "(ss)", &t, &a)) > 0) { + _cleanup_free_ SocketPort *p = NULL; + + p = new0(SocketPort, 1); + if (!p) + return log_oom(); + + p->type = socket_type_from_string(t); + if (p->type < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown Socket type: %s", t); + + if (p->type != SOCKET_SOCKET) { + p->path = strdup(a); + path_kill_slashes(p->path); + + } else if (streq(t, "Netlink")) { + r = socket_address_parse_netlink(&p->address, a); + if (r < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid netlink address: %s", a); + + } else { + r = socket_address_parse(&p->address, a); + if (r < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address: %s", a); + + p->address.type = socket_address_type_from_string(t); + if (p->address.type < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address type: %s", t); + + if (socket_address_family(&p->address) != AF_LOCAL && p->address.type == SOCK_SEQPACKET) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Address family not supported: %s", a); + } + + p->fd = -1; + p->auxiliary_fds = NULL; + p->n_auxiliary_fds = 0; + p->socket = s; + + empty = false; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + SocketPort *tail; + + LIST_FIND_TAIL(port, s->ports, tail); + LIST_INSERT_AFTER(port, s->ports, tail, p); + + p = NULL; + + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "Listen%s=%s", t, a); + } + } + if (r < 0) + return r; + + r = sd_bus_message_exit_container(message); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) { + socket_free_ports(s); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "ListenStream="); + } + + return 1; + + } else if ((ci = socket_exec_command_from_string(name)) >= 0) + return bus_exec_command_set_transient_property(UNIT(s), name, &s->exec_command[ci], message, flags, error); + + return 0; +} + int bus_socket_set_property( Unit *u, const char *name, @@ -170,12 +629,37 @@ int bus_socket_set_property( sd_bus_error *error) { Socket *s = SOCKET(u); + int r; + + assert(s); + assert(name); + assert(message); assert(s); assert(name); assert(message); - return bus_cgroup_set_property(u, &s->cgroup_context, name, message, flags, error); + r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, flags, error); + if (r != 0) + return r; + + if (u->transient && u->load_state == UNIT_STUB) { + /* This is a transient unit, let's load a little more */ + + r = bus_socket_set_transient_property(s, name, message, flags, error); + if (r != 0) + return r; + + r = bus_exec_context_set_transient_property(u, &s->exec_context, name, message, flags, error); + if (r != 0) + return r; + + r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, flags, error); + if (r != 0) + return r; + } + + return 0; } int bus_socket_commit_properties(Unit *u) { diff --git a/src/core/socket.c b/src/core/socket.c index 6baaa8840e..553bbe9f76 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -3281,6 +3281,8 @@ const UnitVTable socket_vtable = { "Install\0", .private_section = "Socket", + .can_transient = true, + .init = socket_init, .done = socket_done, .load = socket_load, |