diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2021-03-28 03:00:57 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2021-03-28 03:00:57 +0000 |
commit | b4c668f3e138733548dfd36b3bcbd8dbbd143985 (patch) | |
tree | d8f51c68770f7bc184723725bc737023327e7874 | |
parent | e2959c22c7309836d6f5dba2f0db7b293b860ad8 (diff) | |
download | s6-rc-b4c668f3e138733548dfd36b3bcbd8dbbd143985.tar.xz |
Some more stuff, especially server-side monitor
-rw-r--r-- | src/include/s6-rc/event.h | 1 | ||||
-rw-r--r-- | src/server/client.c | 44 | ||||
-rw-r--r-- | src/server/client.h | 10 | ||||
-rw-r--r-- | src/server/command.c | 69 | ||||
-rw-r--r-- | src/server/command.h | 1 | ||||
-rw-r--r-- | src/server/db.h | 6 | ||||
-rw-r--r-- | src/server/ep.c | 2 | ||||
-rw-r--r-- | src/server/ev.h | 2 | ||||
-rw-r--r-- | src/server/main.h | 2 |
9 files changed, 86 insertions, 51 deletions
diff --git a/src/include/s6-rc/event.h b/src/include/s6-rc/event.h index fe944e7..8a08dcb 100644 --- a/src/include/s6-rc/event.h +++ b/src/include/s6-rc/event.h @@ -5,6 +5,7 @@ #include <stdint.h> + typedef enum s6rc_eventtype_e s6rc_eventtype_t, *s6rc_eventtype_t_ref ; enum s6rc_eventtype_e { diff --git a/src/server/client.c b/src/server/client.c index 3984553..c69794f 100644 --- a/src/server/client.c +++ b/src/server/client.c @@ -57,18 +57,8 @@ void client_yoink (client_t **c) client_connections-- ; } -void client_setdeadline (client_t *c) -{ - tain_t blah ; - tain_half(&blah, &tain_infinite_relative) ; - tain_add_g(&blah, &blah) ; - if (tain_less(&blah, &c->deadline)) - tain_add_g(&c->deadline, &client_answer_tto) ; -} - int client_prepare_iopause (client_t *c, tain_t *deadline, iopause_fd *x, uint32_t *j) { - if (tain_less(&c->deadline, deadline)) *deadline = c->deadline ; if (!textmessage_sender_isempty(&c->connection.out) || !textmessage_receiver_isempty(&c->connection.in) || (!flags.lameduck && !textmessage_receiver_isfull(&c->connection.in))) { x[*j].fd = textmessage_sender_fd(&c->connection.out) ; @@ -83,6 +73,12 @@ int client_prepare_iopause (client_t *c, tain_t *deadline, iopause_fd *x, uint32 c->xindex[1] = (*j)++ ; } else c->xindex[1] = 0 ; + if (!textmessage_sender_isempty(&c->connection.out) || (ismonitored(c) && !textmessage_sender_isempty(&c->monitor))) + { + tain_t foo ; + tain_add_g(&foo, &client_answer_tto) ; + if (tain_less(&foo, deadline)) *deadline = foo ; + } return !!c->xindex[0] || !!c->xindex[1] ; } @@ -91,7 +87,6 @@ int client_add (int fd, uint8_t perms) client_t *c = alloc(sizeof(client_t)) ; if (!c) return 0 ; c->xindex[0] = c->xindex[1] = 0 ; - tain_add_g(&c->deadline, &client_answer_tto) ; c->perms = perms ; c->monitor = textmessage_sender_zero ; textmessage_sender_init(&c->connection.out, fd) ; @@ -107,24 +102,16 @@ int client_add (int fd, uint8_t perms) int client_flush (client_t *c, iopause_fd const *x) { int ok = 1 ; - int done = 1 ; if (c->xindex[0] && (x[c->xindex[0]].revents & IOPAUSE_WRITE)) { - if (!textmessage_sender_flush(&c->connection.out)) - { - done = 0 ; - if (!error_isagain(errno)) ok = 0 ; - } + if (!textmessage_sender_flush(&c->connection.out) && !error_isagain(errno)) + ok = 0 ; } if (ismonitored(c) && c->xindex[1] && (x[c->xindex[1]].revents & IOPAUSE_WRITE)) { - if (!textmessage_sender_flush(&c->monitor)) - { - done = 0 ; - if (!error_isagain(errno)) ok = 0 ; - } + if (!textmessage_sender_flush(&c->monitor) && !error_isagain(errno)) + monitor_finish(c) ; } - if (done) tain_add_g(&c->deadline, &tain_infinite_relative) ; return ok ; } @@ -134,15 +121,6 @@ int client_read (client_t *c, iopause_fd const *x) textmessage_handle(&c->connection.in, command_handle, c) > 0 : 1 ; } -int monitor_init (client_t *c, int fd, unsigned int v) -{ - if (ismonitored(c)) return (errno = EINVAL, 0) ; - textmessage_sender_init(&c->monitor, fd) ; - c->monitor_verbosity = v ; - client_monitors++ ; - return 1 ; -} - void monitor_finish (client_t *c) { if (!ismonitored(c)) return ; @@ -152,7 +130,7 @@ void monitor_finish (client_t *c) client_monitors-- ; } -void monitor_put (unsigned int v, char const *s, size_t len) +void monitor_put (uint32_t v, char const *s, size_t len) { if (!client_monitors) return ; for (client_t *c = client_head ; c ; c = c->next) diff --git a/src/server/client.h b/src/server/client.h index 4a6ad6c..4b6cccc 100644 --- a/src/server/client.h +++ b/src/server/client.h @@ -20,13 +20,12 @@ struct client_s client_t *prev ; client_t *next ; uint32_t xindex[2] ; - tain_t deadline ; s6rc_connection_t connection ; textmessage_sender_t monitor ; - unsigned int monitor_verbosity ; + uint32_t monitor_verbosity ; uint8_t perms ; } ; -#define CLIENT_ZERO { .next = 0, .xindex = 0, .deadline = TAIN_ZERO, .connection = S6RC_CONNECTION_ZERO, .monitor = TEXTMESSAGE_SENDER_ZERO, .monitor_verbosity = 0, .perms = 0 } +#define CLIENT_ZERO { .next = 0, .xindex = 0, .connection = S6RC_CONNECTION_ZERO, .monitor = TEXTMESSAGE_SENDER_ZERO, .monitor_verbosity = 0, .perms = 0 } extern tain_t client_answer_tto ; extern client_t *client_head ; @@ -37,14 +36,11 @@ extern int client_prepare_iopause (client_t *, tain_t *, iopause_fd *, uint32_t extern int client_flush (client_t *, iopause_fd const *) ; extern int client_add (int, uint8_t) ; -extern void client_setdeadline (client_t *) ; - /* Monitors */ extern uint32_t client_monitors ; -extern int monitor_init (client_t *, int) ; extern int monitor_finish (client_t *) ; -extern int monitor_put (unsigned int, char const *, size_t) ; +extern int monitor_put (uint32_t, char const *, size_t) ; #endif diff --git a/src/server/command.c b/src/server/command.c index c52dc8b..9127714 100644 --- a/src/server/command.c +++ b/src/server/command.c @@ -3,26 +3,85 @@ #include <errno.h> #include <sys/uio.h> +#include <skalibs/uint32.h> #include <skalibs/textmessage.h> #include <skalibs/posixishard.h> #include "client.h" #include "command.h" -static int answer (client_t *c, char e) +static inline int answer (client_t *c, char e) { - if (!textmessage_put(&c->connection.out, &e, 1)) return 0 ; - client_setdeadline(c) ; - return 1 ; + return textmessage_put(&c->connection.out, &e, 1) ; } static int do_query (client_t *c, char const *s, size_t len) { if (!len--) return (errno = EPROTO, 0) ; + return 1 ; +} + +static inline int do_monitor_stop (client_t *c) +{ + monitor_finish(c) ; + return answer(0) ; +} + +static inline int do_monitor_start (client_t *c, uint32_t v) +{ + if (textmessage_sender_fd(&c->monitor) >= 0) return answer(c, EBUSY) ; + if (!answer(c, 0)) return 0 ; + + /* + XXX: due to the nature of ancil, we have to do a couple sync + writes here, which may mess up our async engine. But in practice, + with such small data, kernel buffers make it so writes/sendmsgs + are always instantly accepted, so we get away with it. + */ + + tain_t deadline ; + tain_addsec_g(&deadline, 2) ; + if (!textmessage_sender_timed_flush_g(&c->connection.out, &deadline) + || !textmessage_create_send_channel_g(textmessage_sender_fd(&c->connection.out), &c->monitor, S6RC_MONITOR_BANNER, S6RC_MONITOR_BANNERLEN, &deadline)) + return 0 ; + c->monitor_verbosity = v ; + client_monitors++ ; + return 1 ; } static int do_monitor (client_t *c, char const *s, size_t len) { + if (!len--) return (errno = EPROTO, 0) ; + if (!(c->flags & 2)) return answer(c, EPERM) ; + switch (*s++) + { + case '+' : + { + uint32_t v ; + if (len != 4) return (errno = EPROTO, 0) ; + uint32_unpack_big(s, &v) ; + return do_monitor_start(c, v) ; + } + case '-' : + if (len) return (errno = EPROTO, 0) ; + return do_monitor_stop(c, s, len) ; + default : return (errno = EPROTO, 0) ; + } +} + +static int do_change (client_t *c, char const *s, size_t len) +{ + return 1 ; +} + +static int do_event (client_t *c, char const *s, size_t len) +{ + return 1 ; +} + +static int do_admin (client_t *c, char const *s, size_t len) +{ + return 1 ; } int command_handle (struct iovec const *v, void *aux) @@ -38,6 +97,6 @@ int command_handle (struct iovec const *v, void *aux) case '?' : return do_change(c, s, len) ; case '!' : return do_event(c, s, len) ; case '#' : return do_admin(c, s, len) ; - default : return do_error(c) ; + default : return (errno = EPROTO, 0) ; } } diff --git a/src/server/command.h b/src/server/command.h index 4edfb09..bb16efd 100644 --- a/src/server/command.h +++ b/src/server/command.h @@ -5,7 +5,6 @@ #include <sys/uio.h> -#include <skalibs/textmessage.h> /* Client commands */ diff --git a/src/server/db.h b/src/server/db.h index efe799d..2c960bc 100644 --- a/src/server/db.h +++ b/src/server/db.h @@ -3,9 +3,11 @@ #ifndef S6RCD_DB_H #define S6RCD_DB_H +#include <s6-rc/db.h> + /* Service database */ -extern int s6rcd_db_load (s6rc_db_t *, char const *) ; -extern int s6rcd_db_read_sizes (s6rc_db_sizes_t *, char const *) ; +extern int db_load (s6rc_db_t *, char const *) ; +extern int db_read_sizes (s6rc_db_sizes_t *, char const *) ; #endif diff --git a/src/server/ep.c b/src/server/ep.c index 2fa0c0e..f5557a5 100644 --- a/src/server/ep.c +++ b/src/server/ep.c @@ -79,7 +79,6 @@ int ep_add (uint8_t type, char const *name, uint32_t owner, ep_func_t_ref f, voi { epelem_t ee = { .owner = owner, .f = f, .aux = aux } ; uint32_t d ; - if (type >= S6RC_EVENTTYPE_PHAIL) return (errno = EINVAL, 0) ; if (!avltree_search(&ep[type].map, name, &d)) { eplist_t newlist = { .name = name, .list = GENALLOC_ZERO } ; @@ -97,7 +96,6 @@ int ep_add (uint8_t type, char const *name, uint32_t owner, ep_func_t_ref f, voi void ep_delete (uint8_t type, char const *name, uint32_t owner, ep_func_t_ref f, void *aux) { uint32_t d ; - if (type >= S6RC_EVENTTYPE_PHAIL) return ; if (!avltree_search(&ep[type].map, name, &d)) return ; epelem_t ee = { .owner = owner, .f = f, .aux = aux } ; diff --git a/src/server/ev.h b/src/server/ev.h index c267a40..67fe3c1 100644 --- a/src/server/ev.h +++ b/src/server/ev.h @@ -12,7 +12,7 @@ extern int ev_enqueue (s6rc_event_t const *) ; extern int ev_pop (s6rc_event_t *) ; - /* Event processor: the static part */ + /* Event processor: the builtin part */ extern void ev_handle (s6rc_event_t const *) ; diff --git a/src/server/main.h b/src/server/main.h index 84d6688..c8495a7 100644 --- a/src/server/main.h +++ b/src/server/main.h @@ -3,12 +3,14 @@ #ifndef S6RCD_MAIN_H #define S6RCD_MAIN_H + /* Exported by the main file, s6-rcd.c */ typedef struct globalflags_s globalflags_t, *globalflags_t_ref ; struct globalflags_s { uint8_t lameduck : 1 ; + uint8_t dbupdate : 1 ; } ; extern globalflags_t flags ; |