[systemd-devel] [PATCHv4] core: notify triggered by socket of a service

Lennart Poettering lennart at poettering.net
Thu Sep 12 09:47:44 PDT 2013


On Mon, 22.07.13 10:52, Umut Tezduyar (umut at tezduyar.com) wrote:

Thanks!

Applied!

> ---
>  TODO               |    3 ---
>  src/core/service.c |   31 -------------------------------
>  src/core/socket.c  |   39 ++++++++++++++++++++++++++++++++++++++-
>  src/core/socket.h  |    3 ---
>  4 files changed, 38 insertions(+), 38 deletions(-)
> 
> diff --git a/TODO b/TODO
> index ba8bb8e..e0c4857 100644
> --- a/TODO
> +++ b/TODO
> @@ -115,9 +115,6 @@ Features:
>    Maybe take a BSD lock at the disk device node and teach udev to
>    check for that and suppress event handling.
>  
> -* when a service changes state make reflect that in the
> -  RUNNING/LISTENING states of its socket
> -
>  * when recursively showing the cgroup hierarchy, optionally also show
>    the hierarchies of child processes
>  
> diff --git a/src/core/service.c b/src/core/service.c
> index b98f11a..157d614 100644
> --- a/src/core/service.c
> +++ b/src/core/service.c
> @@ -1481,24 +1481,6 @@ static int service_search_main_pid(Service *s) {
>          return 0;
>  }
>  
> -static void service_notify_sockets_dead(Service *s, bool failed_permanent) {
> -        Iterator i;
> -        Unit *u;
> -
> -        assert(s);
> -
> -        /* Notifies all our sockets when we die */
> -
> -        if (s->socket_fd >= 0)
> -                return;
> -
> -        SET_FOREACH(u, UNIT(s)->dependencies[UNIT_TRIGGERED_BY], i)
> -                if (u->type == UNIT_SOCKET)
> -                        socket_notify_service_dead(SOCKET(u), failed_permanent);
> -
> -        return;
> -}
> -
>  static void service_set_state(Service *s, ServiceState state) {
>          ServiceState old_state;
>          const UnitActiveState *table;
> @@ -1550,19 +1532,6 @@ static void service_set_state(Service *s, ServiceState state) {
>                  s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID;
>          }
>  
> -        if (state == SERVICE_FAILED)
> -                service_notify_sockets_dead(s, s->result == SERVICE_FAILURE_START_LIMIT);
> -
> -        if (state == SERVICE_DEAD ||
> -            state == SERVICE_STOP ||
> -            state == SERVICE_STOP_SIGTERM ||
> -            state == SERVICE_STOP_SIGKILL ||
> -            state == SERVICE_STOP_POST ||
> -            state == SERVICE_FINAL_SIGTERM ||
> -            state == SERVICE_FINAL_SIGKILL ||
> -            state == SERVICE_AUTO_RESTART)
> -                service_notify_sockets_dead(s, false);
> -
>          if (state != SERVICE_START_PRE &&
>              state != SERVICE_START &&
>              state != SERVICE_START_POST &&
> diff --git a/src/core/socket.c b/src/core/socket.c
> index cf88bae..2130e48 100644
> --- a/src/core/socket.c
> +++ b/src/core/socket.c
> @@ -2277,7 +2277,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!
> @@ -2322,6 +2322,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);
>  }
> @@ -2402,6 +2437,8 @@ 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",
> diff --git a/src/core/socket.h b/src/core/socket.h
> index 8f9dfdb..5733322 100644
> --- a/src/core/socket.h
> +++ b/src/core/socket.h
> @@ -156,9 +156,6 @@ struct Socket {
>  /* Called from the service code when collecting fds */
>  int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds);
>  
> -/* Called from the service when it shut down */
> -void socket_notify_service_dead(Socket *s, bool failed_permanent);
> -
>  /* Called from the mount code figure out if a mount is a dependency of
>   * any of the sockets of this socket */
>  int socket_add_one_mount_link(Socket *s, Mount *m);


Lennart

-- 
Lennart Poettering - Red Hat, Inc.


More information about the systemd-devel mailing list