diff --git a/flock/Makefile b/flock/Makefile index c873e169..a108abbb 100644 --- a/flock/Makefile +++ b/flock/Makefile @@ -1,4 +1,4 @@ -src := ctl.c flock.c hypervisor.c +src := container.c ctl.c flock.c hypervisor.c obj := $(src-o-files) flock=$(exedir)/flock-sim diff --git a/flock/container.c b/flock/container.c new file mode 100644 index 00000000..f062095e --- /dev/null +++ b/flock/container.c @@ -0,0 +1,22 @@ +#include "lib/birdlib.h" +#include "lib/cbor.h" +#include "lib/io-loop.h" + +#include "flock/flock.h" + +#include + +void +container_start(struct birdsock *s, struct flock_machine_container_config *cfg) +{ + log(L_INFO "Requested to start a container, name %s, base %s, work %s", + cfg->cf.name, cfg->basedir, cfg->workdir); + + struct linpool *lp = lp_new(s->pool); + struct cbor_writer *cw = cbor_init(s->tbuf, s->tbsize, lp); + cbor_open_block_with_length(cw, 1); + cbor_add_int(cw, -1); + cbor_add_string(cw, "OK"); + sk_send(s, cw->pt); + rfree(lp); +} diff --git a/flock/ctl.c b/flock/ctl.c index e2dc8f51..0291e5c1 100644 --- a/flock/ctl.c +++ b/flock/ctl.c @@ -15,7 +15,8 @@ * - 0 with NULL (7-22) = shutdown the hypervisor * - 1 with NULL = open a telnet listener * - 2 with NULL = close the telnet listener (if not used) - * - 3 with array of strings = run the given command inside the hypervisor + * - 3 with one string = create a machine of this name + * - 4 with array of strings = run the given command inside the hypervisor */ struct cbor_parser_context { @@ -45,6 +46,9 @@ struct cbor_parser_context { #define LOCAL_STACK_MAX_DEPTH 3 u64 stack_countdown[LOCAL_STACK_MAX_DEPTH]; uint stack_pos; + + /* Specific */ + union flock_machine_config cfg; }; #define CBOR_PARSER_ERROR(...) do { \ @@ -158,7 +162,7 @@ hcs_parse(struct cbor_parser_context *ctx, const byte *buf, s64 size) if (ctx->type != 0) CBOR_PARSER_ERROR("Expected integer, got %u", ctx->type); - if (ctx->value >= 4) + if (ctx->value >= 5) CBOR_PARSER_ERROR("Command key too high, got %lu", ctx->value); ctx->major_state = ctx->value + 2; @@ -201,10 +205,86 @@ hcs_parse(struct cbor_parser_context *ctx, const byte *buf, s64 size) ctx->major_state = 1; break; - case 5: /* process spawner */ + case 5: /* machine creation request */ + if (ctx->type != 5) + CBOR_PARSER_ERROR("Expected mapping, got %u", ctx->type); + + ctx->major_state = 501; + break; + + case 6: /* process spawner */ CBOR_PARSER_ERROR("NOT IMPLEMENTED YET"); break; + case 501: /* machine creation argument */ + if (ctx->type != 0) + CBOR_PARSER_ERROR("Expected integer, got %u", ctx->type); + + if (ctx->value >= 5) + CBOR_PARSER_ERROR("Command key too high, got %lu", ctx->value); + + ctx->major_state = ctx->value + 502; + break; + + case 502: /* machine creation argument 0: name */ + if (ctx->type != 3) + CBOR_PARSER_ERROR("Expected string, got %u", ctx->type); + + if (value_is_special) + CBOR_PARSER_ERROR("Variable length string not supported yet"); + + if (ctx->cfg.cf.name) + CBOR_PARSER_ERROR("Duplicate argument 0 / name"); + + ASSERT_DIE(!ctx->target_buf); + ctx->cfg.cf.name = ctx->target_buf = lp_alloc(ctx->lp, ctx->value + 1); + ctx->target_len = ctx->value; + break; + + case 503: /* machine creation argument 1: type */ + if (ctx->type != 0) + CBOR_PARSER_ERROR("Expected integer, got %u", ctx->type); + + if (ctx->cfg.cf.type) + CBOR_PARSER_ERROR("Duplicate argument 1 / type, already have %d", ctx->cfg.cf.type); + + if ((ctx->value < 1) && (ctx->value > 1) ) + CBOR_PARSER_ERROR("Unexpected type, got %lu", ctx->value); + + ctx->cfg.cf.type = ctx->value; + ctx->major_state = 501; + break; + + case 504: /* machine creation argument 2: workdir */ + if (ctx->type != 2) + CBOR_PARSER_ERROR("Expected bytestring, got %u", ctx->type); + + if (value_is_special) + CBOR_PARSER_ERROR("Variable length string not supported yet"); + + if (ctx->cfg.container.workdir) + CBOR_PARSER_ERROR("Duplicate argument 2 / workdir"); + + ASSERT_DIE(!ctx->target_buf); + ctx->cfg.container.workdir = ctx->target_buf = lp_alloc(ctx->lp, ctx->value + 1); + ctx->target_len = ctx->value; + break; + + case 505: /* machine creation argument 3: basedir */ + if (ctx->type != 2) + CBOR_PARSER_ERROR("Expected bytestring, got %u", ctx->type); + + if (value_is_special) + CBOR_PARSER_ERROR("Variable length string not supported yet"); + + if (ctx->cfg.container.basedir) + CBOR_PARSER_ERROR("Duplicate argument 3 / basedir"); + + ASSERT_DIE(!ctx->target_buf); + ctx->cfg.container.basedir = ctx->target_buf = lp_alloc(ctx->lp, ctx->value + 1); + ctx->target_len = ctx->value; + break; + default: bug("invalid parser state"); } @@ -256,11 +336,20 @@ hcs_parse(struct cbor_parser_context *ctx, const byte *buf, s64 size) /* Actually not this one */ CBOR_PARSER_ERROR("NOT IMPLEMENTED YET"); + case 502: + case 504: + case 505: + ctx->major_state = 501; + break; + default: bug("Unexpected state to end a (byte)string in"); /* Code to run at the end of a (byte)string */ } + ctx->target_buf = NULL; + ctx->partial_state = CPE_TYPE; + exit_stack = !--ctx->stack_countdown[ctx->stack_pos]; } @@ -284,6 +373,23 @@ hcs_parse(struct cbor_parser_context *ctx, const byte *buf, s64 size) ctx->major_state = 1; break; + case 501: + if (!ctx->cfg.cf.type) + CBOR_PARSER_ERROR("Machine type not specified"); + + if (!ctx->cfg.cf.name) + CBOR_PARSER_ERROR("Machine name not specified"); + + if (!ctx->cfg.container.workdir) + CBOR_PARSER_ERROR("Machine workdir not specified"); + + if (!ctx->cfg.container.basedir) + CBOR_PARSER_ERROR("Machine basedir not specified"); + + container_start(ctx->sock, &ctx->cfg.container); + ctx->major_state = 1; + break; + default: bug("Unexpected state to end a mapping in"); } diff --git a/flock/flock.h b/flock/flock.h index 076d7141..22637975 100644 --- a/flock/flock.h +++ b/flock/flock.h @@ -27,6 +27,23 @@ bool hcs_complete(struct cbor_parser_context *ctx); void hexp_get_telnet(sock *, const char *name); +union flock_machine_config { + struct flock_machine_common_config { + const char *name; + enum { + FLOCK_MACHINE_NONE = 0, + FLOCK_MACHINE_CONTAINER = 1, + } type; + } cf; + struct flock_machine_container_config { + struct flock_machine_common_config cf; + const char *workdir; + const char *basedir; + } container; +}; + +void container_start(sock *, struct flock_machine_container_config *); + extern event reboot_event, poweroff_event; extern event_list shutdown_event_list; diff --git a/flock/hypervisor.c b/flock/hypervisor.c index 9ec1d860..d69959cc 100644 --- a/flock/hypervisor.c +++ b/flock/hypervisor.c @@ -108,7 +108,6 @@ hypervisor_control_socket(void) s->rbsize = 1024; s->tbsize = 1024; - unlink(flock_config.control_socket_path); if (sk_open_unix(s, loop, flock_config.control_socket_path) < 0) die("Can't create control socket %s: %m", flock_config.control_socket_path);