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

Umut Tezduyar umut at tezduyar.com
Fri Jul 12 00:19:20 PDT 2013


On Wed, Jul 10, 2013 at 2:24 PM, Umut Tezduyar <umut at tezduyar.com> wrote:
> On Wed, Jul 10, 2013 at 9:19 AM, Umut Tezduyar <umut at tezduyar.com> wrote:
>> ---
>>  systemd/src/core/service.c |   31 -------------------------------
>>  systemd/src/core/socket.c  |   33 ++++++++++++++++++++++++++++++++-
>>  systemd/src/core/socket.h  |    3 ---
>>  3 files changed, 32 insertions(+), 35 deletions(-)
>>
>> diff --git a/src/core/service.c b/src/core/service.c
>> index 3617c24..78ee272 100644
>> --- a/src/core/service.c
>> +++ b/src/core/service.c
>> @@ -1474,24 +1474,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;
>> @@ -1543,19 +1525,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 1b08f0a..21bbba5 100644
>> --- a/src/core/socket.c
>> +++ b/src/core/socket.c
>> @@ -2261,7 +2261,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!
>> @@ -2306,6 +2306,35 @@ 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);
>> +
>> +        if (other->load_state != UNIT_LOADED ||
>> +            other->type != UNIT_SERVICE)
>> +                return;
>> +
>> +        if (se->state == SERVICE_FAILED && se->socket_fd < 0)
>> +                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) &&
>> +            se->socket_fd < 0)
>> +                socket_notify_service_dead(s, false);
>> +
>> +        if (se->state == SERVICE_RUNNING)
>> +                socket_set_state(s, SOCKET_RUNNING);
> This doesn't work for socket activated/instantiated services. I should
> be able to detect if a service is instantiated..

Lennart, do you have a solution for this that I can take in and
re-send the patch?  It works great for socket activated services that
when service is running, the triggered by socket is set to running too
but it is not working for instantiated services. For instantiated
services, socket needs to stay in "listening" stay all the time.

>> +}
>> +
>>  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);
>>  }
>> @@ -2385,6 +2414,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 9d48cde..9714303 100644
>> --- a/src/core/socket.h
>> +++ b/src/core/socket.h
>> @@ -154,9 +154,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);
>> --
>> 1.7.2.5
>>


More information about the systemd-devel mailing list