From: Lennart Poettering Date: Thu, 10 Jul 2014 20:47:55 +0000 (+0200) Subject: machined: allow registering host-side network interfaces for communication with conta... X-Git-Tag: v216~676 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=9b5ed6feda08290edce3bf916fa7362733dd30ea machined: allow registering host-side network interfaces for communication with containers --- diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index 3741485a7..72e0a701b 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -83,6 +83,31 @@ static int property_get_state( return 1; } +static int property_get_netif( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + Machine *m = userdata; + int r; + + assert(bus); + assert(reply); + assert(m); + + assert_cc(sizeof(int) == sizeof(int32_t)); + + r = sd_bus_message_append_array(reply, 'i', m->netif, m->n_netif * sizeof(int)); + if (r < 0) + return r; + + return 1; +} + static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_class, machine_class, MachineClass); int bus_machine_method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { @@ -376,6 +401,7 @@ const sd_bus_vtable machine_vtable[] = { SD_BUS_PROPERTY("Leader", "u", NULL, offsetof(Machine, leader), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Machine, class), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(Machine, root_directory), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("NetworkInterfaces", "ai", property_get_netif, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0), SD_BUS_METHOD("Terminate", NULL, NULL, bus_machine_method_terminate, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)), SD_BUS_METHOD("Kill", "si", NULL, bus_machine_method_kill, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)), diff --git a/src/machine/machine.c b/src/machine/machine.c index cf38e3fb9..0ed18d74e 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -94,6 +94,7 @@ void machine_free(Machine *m) { free(m->state_file); free(m->service); free(m->root_directory); + free(m->netif); free(m); } @@ -176,6 +177,21 @@ int machine_save(Machine *m) { m->timestamp.realtime, m->timestamp.monotonic); + if (m->n_netif > 0) { + unsigned i; + + fputs("NETIF=", f); + + for (i = 0; i < m->n_netif; i++) { + if (i != 0) + fputc(' ', f); + + fprintf(f, "%i", m->netif[i]); + } + + fputc('\n', f); + } + r = fflush_and_check(f); if (r < 0) goto finish; @@ -222,7 +238,7 @@ static void machine_unlink(Machine *m) { } int machine_load(Machine *m) { - _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *id = NULL, *leader = NULL, *class = NULL; + _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *id = NULL, *leader = NULL, *class = NULL, *netif = NULL; int r; assert(m); @@ -237,6 +253,7 @@ int machine_load(Machine *m) { "CLASS", &class, "REALTIME", &realtime, "MONOTONIC", &monotonic, + "NETIF", &netif, NULL); if (r < 0) { if (r == -ENOENT) @@ -272,6 +289,35 @@ int machine_load(Machine *m) { m->timestamp.monotonic = l; } + if (netif) { + size_t l, allocated = 0, nr = 0; + char *w, *state; + int *ni = NULL; + + FOREACH_WORD(w, l, netif, state) { + char buf[l+1]; + int ifi; + + *(char*) (mempcpy(buf, w, l)) = 0; + + if (safe_atoi(buf, &ifi) < 0) + continue; + if (ifi <= 0) + continue; + + if (!GREEDY_REALLOC(ni, allocated, nr+1)) { + free(ni); + return log_oom(); + } + + ni[nr++] = ifi; + } + + free(m->netif); + m->netif = ni; + m->n_netif = nr; + } + return r; } diff --git a/src/machine/machine.h b/src/machine/machine.h index fa9262d52..5c6366554 100644 --- a/src/machine/machine.h +++ b/src/machine/machine.h @@ -76,6 +76,9 @@ struct Machine { sd_bus_message *create_message; + int *netif; + unsigned n_netif; + LIST_FIELDS(Machine, gc_queue); }; diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index a041444b7..1b9449a2b 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -151,14 +151,15 @@ static int method_list_machines(sd_bus *bus, sd_bus_message *message, void *user return sd_bus_send(bus, reply, NULL); } -static int method_create_or_register_machine(Manager *manager, sd_bus_message *message, Machine **_m, sd_bus_error *error) { +static int method_create_or_register_machine(Manager *manager, sd_bus_message *message, bool read_network, Machine **_m, sd_bus_error *error) { const char *name, *service, *class, *root_directory; + const int32_t *netif = NULL; MachineClass c; uint32_t leader; sd_id128_t id; const void *v; Machine *m; - size_t n; + size_t n, n_netif = 0; int r; assert(manager); @@ -185,6 +186,21 @@ static int method_create_or_register_machine(Manager *manager, sd_bus_message *m if (r < 0) return r; + if (read_network) { + size_t i; + + r = sd_bus_message_read_array(message, 'i', (const void**) &netif, &n_netif); + if (r < 0) + return r; + + n_netif /= sizeof(int32_t); + + for (i = 0; i < n_netif; i++) { + if (netif[i] <= 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid network interface index %i", netif[i]); + } + } + if (isempty(class)) c = _MACHINE_CLASS_INVALID; else { @@ -240,6 +256,17 @@ static int method_create_or_register_machine(Manager *manager, sd_bus_message *m } } + if (n_netif > 0) { + assert_cc(sizeof(int32_t) == sizeof(int)); + m->netif = memdup(netif, sizeof(int32_t) * n_netif); + if (!m->netif) { + r = -ENOMEM; + goto fail; + } + + m->n_netif = n_netif; + } + *_m = m; return 1; @@ -249,12 +276,12 @@ fail: return r; } -static int method_create_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { +static int method_create_machine_internal(sd_bus *bus, sd_bus_message *message, bool read_network, void *userdata, sd_bus_error *error) { Manager *manager = userdata; Machine *m = NULL; int r; - r = method_create_or_register_machine(manager, message, &m, error); + r = method_create_or_register_machine(manager, message, read_network, &m, error); if (r < 0) return r; @@ -274,13 +301,21 @@ fail: return r; } -static int method_register_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { +static int method_create_machine_with_network(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { + return method_create_machine_internal(bus, message, true, userdata, error); +} + +static int method_create_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { + return method_create_machine_internal(bus, message, false, userdata, error); +} + +static int method_register_machine_internal(sd_bus *bus, sd_bus_message *message, bool read_network, void *userdata, sd_bus_error *error) { Manager *manager = userdata; _cleanup_free_ char *p = NULL; Machine *m = NULL; int r; - r = method_create_or_register_machine(manager, message, &m, error); + r = method_create_or_register_machine(manager, message, read_network, &m, error); if (r < 0) return r; @@ -309,6 +344,14 @@ fail: return r; } +static int method_register_machine_with_network(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { + return method_register_machine_internal(bus, message, true, userdata, error); +} + +static int method_register_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { + return method_register_machine_internal(bus, message, false, userdata, error); +} + static int method_terminate_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { Manager *m = userdata; Machine *machine; @@ -400,6 +443,8 @@ const sd_bus_vtable manager_vtable[] = { SD_BUS_METHOD("ListMachines", NULL, "a(ssso)", method_list_machines, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("CreateMachine", "sayssusa(sv)", "o", method_create_machine, 0), SD_BUS_METHOD("RegisterMachine", "sayssus", "o", method_register_machine, 0), + SD_BUS_METHOD("CreateMachineWithNetwork", "sayssusaia(sv)", "o", method_create_machine_with_network, 0), + SD_BUS_METHOD("RegisterMachineWithNetwork", "sayssusai", "o", method_register_machine_with_network, 0), SD_BUS_METHOD("KillMachine", "ssi", NULL, method_kill_machine, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)), SD_BUS_METHOD("TerminateMachine", "s", NULL, method_terminate_machine, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)), SD_BUS_METHOD("GetMachineAddresses", "s", "a(yay)", method_get_machine_addresses, SD_BUS_VTABLE_UNPRIVILEGED),