]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Flock: Storing machines (TMP)
authorMaria Matejka <mq@ucw.cz>
Tue, 24 Sep 2024 10:42:18 +0000 (12:42 +0200)
committerMaria Matejka <mq@ucw.cz>
Sun, 23 Feb 2025 18:07:35 +0000 (19:07 +0100)
flock/container.c
flock/ctl.c
flock/flock.h

index 1b6b5a83e3bc783384ba6b568553a566f1ede72c..88c377c5356a11aa54ee0079cec3d0b41892193e 100644 (file)
@@ -3,18 +3,41 @@
 #include "lib/birdlib.h"
 #include "lib/cbor.h"
 #include "lib/io-loop.h"
+#include "lib/hash.h"
 
 #include <sched.h>
 #include <stdlib.h>
 #include <sys/wait.h>
 #include <unistd.h>
 
+static struct hypervisor_container_forker {
+  sock *s;
+  pool *p;
+  struct birdloop *loop;
+  HASH(struct container_runtime) hash;
+  struct container_runtime *cur_crt;
+} hcf;
+
 static struct container_config {
   const char *hostname;
   const char *workdir;
   const char *basedir;
 } ccf;
 
+struct container_runtime {
+  struct container_runtime *next;
+  struct container_config ccf;
+  uint hash;
+  pid_t pid;
+  sock *s;
+  char data[];
+};
+
+#define CRT_KEY(c)     c->ccf.hostname, c->hash
+#define CRT_NEXT(c)    c->next
+#define CRT_EQ(a,h,b,i)        ((h) == (i)) && (!strcmp(a,b))
+#define CRT_FN(a,h)    h
+
 static int container_forker_fd = -1;
 
 static void
@@ -175,25 +198,32 @@ hypervisor_container_forker_rx(sock *sk, uint _sz UNUSED)
   log(L_INFO "Machine started with PID %d", pid);
 
   sock *skl = sk_new(sk->pool);
+  log(L_INFO "skl is %p", skl);
   skl->type = SK_MAGIC;
   skl->rx_hook = hypervisor_container_rx;
   skl->fd = sfd;
   if (sk_open(skl, sk->loop) < 0)
     bug("Machine control socket: sk_open failed");
 
-  /* TODO: create the machine struct
-  struct hexp_received_telnet *hrt = mb_allocz(he.p, sizeof *hrt);
-  *hrt = (struct hexp_received_telnet) {
-    .e = {
-      .hook = hexp_received_telnet,
-      .data = hrt,
-    },
-    .p = sk->data,
-    .port = port,
-    .fd = sfd,
-  };
-  ev_send_loop(hcs_loop, &hrt->e);
-  */
+  ASSERT_DIE(birdloop_inside(hcf.loop));
+
+  ASSERT_DIE(hcf.cur_crt);
+
+  sock *sr = hcf.cur_crt->s;
+  log(L_INFO "sr is %p", sr);
+
+  hcf.cur_crt->pid = pid;
+  hcf.cur_crt->s = skl;
+
+  linpool *lp = lp_new(hcf.p);
+  struct cbor_writer *cw = cbor_init(sr->tbuf, sr->tbsize, lp);
+  cbor_open_block_with_length(cw, 1);
+  cbor_add_int(cw, -1);
+  cbor_add_string(cw, "OK");
+  sk_send(sr, cw->pt);
+  rfree(lp);
+
+  hcf.cur_crt = NULL;
 
   return 0;
 }
@@ -206,16 +236,56 @@ hypervisor_container_forker_err(sock *sk, int e UNUSED)
 
 /* The child */
 
-static struct hypervisor_container_forker {
-  sock *s;
-  pool *p;
-  struct birdloop *loop;
-} hcf;
-
 void
-hypervisor_container_request(const char *name, const char *basedir, const char *workdir)
+hypervisor_container_request(sock *s, const char *name, const char *basedir, const char *workdir)
 {
   birdloop_enter(hcf.loop);
+
+  uint h = mem_hash(name, strlen(name));
+  struct container_runtime *crt = HASH_FIND(hcf.hash, CRT, name, h);
+  if (crt)
+  {
+    linpool *lp = lp_new(hcf.p);
+    struct cbor_writer *cw = cbor_init(s->tbuf, s->tbsize, lp);
+    cbor_open_block_with_length(cw, 1);
+    cbor_add_int(cw, -127);
+    cbor_add_string(cw, "BAD: Already exists");
+
+    sk_send(s, cw->pt);
+
+    birdloop_leave(hcf.loop);
+  }
+
+  uint nlen = strlen(name),
+       blen = strlen(basedir),
+       wlen = strlen(workdir);
+
+  crt = mb_allocz(hcf.p, sizeof *crt + nlen + blen + wlen + 3);
+
+  char *pos = crt->data;
+
+  crt->ccf.hostname = pos;
+  memcpy(pos, name, nlen + 1);
+  pos += nlen + 1;
+
+  crt->ccf.workdir = pos;
+  memcpy(pos, workdir, wlen + 1);
+  pos += wlen + 1;
+
+  crt->ccf.basedir = pos;
+  memcpy(pos, basedir, blen + 1);
+  pos += blen + 1;
+
+  crt->hash = h;
+  crt->s = s;
+
+  HASH_INSERT(hcf.hash, CRT, crt);
+
+  ASSERT_DIE(hcf.cur_crt == NULL);
+  hcf.cur_crt = crt;
+
+  log(L_INFO "requesting machine creation, socket %p", s);
+
   linpool *lp = lp_new(hcf.p);
   struct cbor_writer *cw = cbor_init(hcf.s->tbuf, hcf.s->tbsize, lp);
   cbor_open_block_with_length(cw, 3);
@@ -226,6 +296,8 @@ hypervisor_container_request(const char *name, const char *basedir, const char *
   cbor_add_int(cw, 2);
   cbor_add_string(cw, workdir);
   sk_send(hcf.s, cw->pt);
+  rfree(lp);
+
   birdloop_leave(hcf.loop);
 }
 
@@ -541,6 +613,8 @@ hypervisor_container_fork(void)
     hcf.s->fd = fds[0];
     close(fds[1]);
 
+    HASH_INIT(hcf.hash, hcf.p, 6);
+
     if (sk_open(hcf.s, hcf.loop) < 0)
       bug("Container forker parent: sk_open failed");
 
index f4c3832476667d9937d9f0e85e45fd330b55edee..83433e3d4aea956e7979075aade003a23b66ea16 100644 (file)
@@ -387,6 +387,7 @@ hcs_parse(struct cbor_parser_context *ctx, const byte *buf, s64 size)
            CBOR_PARSER_ERROR("Machine basedir not specified");
 
          hypervisor_container_request(
+             ctx->sock,
              ctx->cfg.cf.name,
              ctx->cfg.container.basedir,
              ctx->cfg.container.workdir);
index a58ee86f7de950659742d85500a4b1d366cf4ddc..01835de9052a82b69ece1a1907013d8ec3080741 100644 (file)
@@ -46,7 +46,7 @@ union flock_machine_config {
 };
 
 
-void hypervisor_container_request(const char *name, const char *basedir, const char *workdir);
+void hypervisor_container_request(sock *s, const char *name, const char *basedir, const char *workdir);
 
 extern event reboot_event, poweroff_event;
 extern event_list shutdown_event_list;