0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-10-18 18:08:45 +00:00
bird/flock/container.c

174 lines
3.7 KiB
C
Raw Normal View History

2024-09-14 20:34:09 +00:00
#include "lib/birdlib.h"
#include "lib/cbor.h"
#include "lib/io-loop.h"
#include "flock/flock.h"
#include <stdlib.h>
2024-09-16 20:48:49 +00:00
static void
container_mainloop(struct flock_machine_container_config *cfg, int fd)
{
log(L_INFO "container mainloop");
/* TODO cleanup the loops from the forked process */
while (1)
{
pause();
log(L_INFO "woken up!");
}
}
struct container_start_callback {
callback cb;
sock *s, *skm;
struct birdloop *loop;
pool *pool;
/* Stored socket hooks */
int (*rx_hook)(sock *, uint size);
void (*err_hook)(sock *, int);
void *data;
/* Actual config */
struct flock_machine_container_config cfg;
};
static void
container_start_sk_err(sock *s, int e)
{
struct container_start_callback *cb = s->data;
cb->skm->data = NULL;
s->data = cb->data;
s->err_hook = cb->err_hook;
mb_free(cb);
s->err_hook(s, e);
}
static int
container_parent_rx(sock *skm, uint size)
{
bug("container_parent_rx");
ASSERT_DIE(size >= 3);
ASSERT_DIE(skm->rbuf[0] == 0xa1);
switch (skm->rbuf[1])
{
case 0:
{
pid_t pid;
if (skm->rbuf[2] < 24)
pid = skm->rbuf[2];
else if (skm->rbuf[2] == 24)
pid = skm->rbuf[3];
else if (skm->rbuf[2] == 25)
pid = skm->rbuf[3] << 8 + skm->rbuf[4];
else if (skm->rbuf[3] == 26)
pid = skm->rbuf[3] << 32 + skm->rbuf[4] << 24 + skm->rbuf[5] << 16 + skm->rbuf[6];
else
bug("not implemented");
log(L_INFO "Machine started with PID %d", pid);
if (!skm->data)
return 1;
struct container_start_callback *cb = skm->data;
struct linpool *lp = lp_new(cb->s->pool);
struct cbor_writer *cw = cbor_init(cb->s->tbuf, cb->s->tbsize, lp);
cbor_open_block_with_length(cw, 1);
cbor_add_int(cw, -1);
cbor_add_string(cw, "OK");
sk_send(cb->s, cw->pt);
rfree(lp);
cb->s->data = cb->data;
cb->s->err_hook = cb->err_hook;
sk_resume_rx(cb->s->loop, cb->s, cb->rx_hook);
mb_free(cb);
return 1;
}
default:
bug("unimplemented");
}
return 1;
}
static void
container_parent_err(sock *s, int e)
{
log(L_ERR "Container parent error hook not implemented: %d (%s)", e, strerror(e));
sk_close(s);
}
static void
container_start_callback(struct callback *_cb)
{
SKIP_BACK_DECLARE(struct container_start_callback, cb, cb, _cb);
ASSERT_DIE(birdloop_inside(&main_birdloop));
log(L_INFO "Requested to start a container, name %s, base %s, work %s",
cb->cfg.cf.name, cb->cfg.basedir, cb->cfg.workdir);
/* create socketpair before forking to do communication */
int fds[2];
int e = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
if (e < 0)
die("Failed to create internal socketpair: %m");
pid_t pid = fork();
if (pid < 0)
die("Failed to fork exposed: %m");
if (!pid)
{
close(fds[0]);
container_mainloop(&cb->cfg, fds[1]); /* this never returns */
bug("container_mainloop has returned");
}
close(fds[1]);
birdloop_enter(cb->loop);
sock *skm = sk_new(cb->pool);
skm->type = SK_MAGIC;
skm->fd = fds[0];
skm->rx_hook = container_parent_rx;
skm->err_hook = container_parent_err;
skm->data = cb;
cb->skm = skm;
if (sk_open(skm, cb->loop) < 0)
bug("Container listener: sk_open failed");
birdloop_leave(cb->loop);
}
2024-09-14 20:34:09 +00:00
void
container_start(struct birdsock *s, struct flock_machine_container_config *cfg)
{
2024-09-16 20:48:49 +00:00
struct container_start_callback *cb = mb_alloc(s->pool, sizeof *cb);
*cb = (struct container_start_callback) {
.cb = callback_init(&cb->cb, container_start_callback, &main_birdloop),
.s = s,
.loop = s->loop,
.pool = s->pool,
.rx_hook = s->rx_hook,
.err_hook = s->err_hook,
.data = s->data,
.cfg = *cfg,
};
sk_pause_rx(s->loop, s);
s->err_hook = container_start_sk_err;
s->data = cb;
callback_activate(&cb->cb);
2024-09-14 20:34:09 +00:00
}