summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2021-03-28 03:00:57 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2021-03-28 03:00:57 +0000
commitb4c668f3e138733548dfd36b3bcbd8dbbd143985 (patch)
treed8f51c68770f7bc184723725bc737023327e7874
parente2959c22c7309836d6f5dba2f0db7b293b860ad8 (diff)
downloads6-rc-b4c668f3e138733548dfd36b3bcbd8dbbd143985.tar.xz
Some more stuff, especially server-side monitor
-rw-r--r--src/include/s6-rc/event.h1
-rw-r--r--src/server/client.c44
-rw-r--r--src/server/client.h10
-rw-r--r--src/server/command.c69
-rw-r--r--src/server/command.h1
-rw-r--r--src/server/db.h6
-rw-r--r--src/server/ep.c2
-rw-r--r--src/server/ev.h2
-rw-r--r--src/server/main.h2
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 ;