X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fsocket.c;h=190b36c3cab4477d8e8b5c6e8c3b02b1f17c3425;hb=13b84ec7df103ce388910a2b868fe1668c1e27ef;hp=2b3b6813cad842aed0d3bc418e974853e2c2273e;hpb=a016b9228f338cb9b380ce7e00826ef462767d98;p=elogind.git diff --git a/src/core/socket.c b/src/core/socket.c index 2b3b6813c..190b36c3c 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -88,6 +88,7 @@ static void socket_init(Unit *u) { s->exec_context.std_output = u->manager->default_std_output; s->exec_context.std_error = u->manager->default_std_error; kill_context_init(&s->kill_context); + cgroup_context_init(&s->cgroup_context); s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID; } @@ -128,6 +129,8 @@ static void socket_done(Unit *u) { socket_free_ports(s); exec_context_done(&s->exec_context, manager_is_reloading_or_reexecuting(u->manager)); + cgroup_context_init(&s->cgroup_context); + exec_command_free_array(s->exec_command, _SOCKET_EXEC_COMMAND_MAX); s->control_command = NULL; @@ -399,10 +402,6 @@ static int socket_load(Unit *u) { if (r < 0) return r; - r = unit_add_default_cgroups(u); - if (r < 0) - return r; - if (UNIT(s)->default_dependencies) if ((r = socket_add_default_dependencies(s)) < 0) return r; @@ -537,6 +536,11 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { "%sMessageQueueMessageSize: %li\n", prefix, s->mq_msgsize); + if (s->reuseport) + fprintf(f, + "%sReusePort: %s\n", + prefix, yes_no(s->reuseport)); + if (s->smack) fprintf(f, "%sSmackLabel: %s\n", @@ -793,6 +797,12 @@ static void socket_apply_socket_options(Socket *s, int fd) { if (setsockopt(fd, SOL_TCP, TCP_CONGESTION, s->tcp_congestion, strlen(s->tcp_congestion)+1) < 0) log_warning_unit(UNIT(s)->id, "TCP_CONGESTION failed: %m"); + if (s->reuseport) { + int b = s->reuseport; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &b, sizeof(b))) + log_warning_unit(UNIT(s)->id, "SO_REUSEPORT failed: %m"); + } + #ifdef HAVE_SMACK if (s->smack_ip_in) if (fsetxattr(fd, "security.SMACK64IPIN", s->smack_ip_in, strlen(s->smack_ip_in), 0) < 0) @@ -1005,7 +1015,7 @@ static int socket_open_fds(Socket *s) { if ((r = socket_instantiate_service(s)) < 0) return r; - if (UNIT_DEREF(s->service) && + if (UNIT_ISSET(s->service) && SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) { r = label_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label); @@ -1210,15 +1220,15 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { assert(c); assert(_pid); + unit_realize_cgroup(UNIT(s)); + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch); if (r < 0) goto fail; - argv = unit_full_printf_strv(UNIT(s), c->argv); - if (!argv) { - r = -ENOMEM; + r = unit_full_printf_strv(UNIT(s), c->argv, &argv); + if (r < 0) goto fail; - } r = exec_spawn(c, argv, @@ -1229,9 +1239,8 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { true, true, UNIT(s)->manager->confirm_spawn, - UNIT(s)->cgroup_bondings, - UNIT(s)->cgroup_attributes, - NULL, + UNIT(s)->manager->cgroup_supported, + UNIT(s)->cgroup_path, UNIT(s)->id, NULL, &pid); @@ -1633,7 +1642,7 @@ static int socket_start(Unit *u) { return 0; /* Cannot run this without the service being around */ - if (UNIT_DEREF(s->service)) { + if (UNIT_ISSET(s->service)) { Service *service; service = SERVICE(UNIT_DEREF(s->service)); @@ -2266,7 +2275,7 @@ int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) { return 0; } -void socket_notify_service_dead(Socket *s, bool failed_permanent) { +static void socket_notify_service_dead(Socket *s, bool failed_permanent) { assert(s); /* The service is dead. Dang! @@ -2311,6 +2320,41 @@ static void socket_reset_failed(Unit *u) { s->result = SOCKET_SUCCESS; } +static void socket_trigger_notify(Unit *u, Unit *other) { + Socket *s = SOCKET(u); + Service *se = SERVICE(other); + + assert(u); + assert(other); + + /* Don't propagate state changes from the service if we are + already down or accepting connections */ + if ((s->state != SOCKET_RUNNING && + s->state != SOCKET_LISTENING) || + s->accept) + return; + + if (other->load_state != UNIT_LOADED || + other->type != UNIT_SERVICE) + return; + + if (se->state == SERVICE_FAILED) + socket_notify_service_dead(s, se->result == SERVICE_FAILURE_START_LIMIT); + + if (se->state == SERVICE_DEAD || + se->state == SERVICE_STOP || + se->state == SERVICE_STOP_SIGTERM || + se->state == SERVICE_STOP_SIGKILL || + se->state == SERVICE_STOP_POST || + se->state == SERVICE_FINAL_SIGTERM || + se->state == SERVICE_FINAL_SIGKILL || + se->state == SERVICE_AUTO_RESTART) + socket_notify_service_dead(s, false); + + if (se->state == SERVICE_RUNNING) + socket_set_state(s, SOCKET_RUNNING); +} + static int socket_kill(Unit *u, KillWho who, int signo, DBusError *error) { return unit_kill_common(u, who, signo, -1, SOCKET(u)->control_pid, error); } @@ -2361,8 +2405,9 @@ const UnitVTable socket_vtable = { "Socket\0" "Install\0", + .private_section = "Socket", .exec_context_offset = offsetof(Socket, exec_context), - .exec_section = "Socket", + .cgroup_context_offset = offsetof(Socket, cgroup_context), .init = socket_init, .done = socket_done, @@ -2390,11 +2435,15 @@ const UnitVTable socket_vtable = { .sigchld_event = socket_sigchld_event, .timer_event = socket_timer_event, + .trigger_notify = socket_trigger_notify, + .reset_failed = socket_reset_failed, .bus_interface = "org.freedesktop.systemd1.Socket", .bus_message_handler = bus_socket_message_handler, .bus_invalidating_properties = bus_socket_invalidating_properties, + .bus_set_property = bus_socket_set_property, + .bus_commit_properties = bus_socket_commit_properties, .status_message_formats = { /*.starting_stopping = {