[systemd-commits] 3 commits - src/machine src/nspawn

Lennart Poettering lennart at kemper.freedesktop.org
Thu Jul 10 14:13:26 PDT 2014


 src/machine/machine-dbus.c  |   26 +++++++++++++++
 src/machine/machine.c       |   48 +++++++++++++++++++++++++++-
 src/machine/machine.h       |    3 +
 src/machine/machinectl.c    |   75 +++++++++++++++++++++++++++++++++++++-------
 src/machine/machined-dbus.c |   57 +++++++++++++++++++++++++++++----
 src/nspawn/nspawn.c         |   44 +++++++++++++++++--------
 6 files changed, 220 insertions(+), 33 deletions(-)

New commits:
commit f48e75cb9a8112d35855c44a156934f2ee0edb2e
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jul 10 23:12:32 2014 +0200

    machinectl: show network interface name for containers
    
    Also, append the if indexes as scope field to the addresses we show.
    That way they may be used for connecting to the containers directly.

diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
index 022a4eb..04c7c7c 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/machinectl.c
@@ -29,6 +29,7 @@
 #include <fcntl.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <net/if.h>
 
 #include "sd-bus.h"
 #include "log.h"
@@ -167,7 +168,7 @@ static int show_unit_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
         return 0;
 }
 
-static int print_addresses(sd_bus *bus, const char *name, const char *prefix, const char *prefix2) {
+static int print_addresses(sd_bus *bus, const char *name, int ifi, const char *prefix, const char *prefix2) {
         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
         int r;
 
@@ -205,7 +206,11 @@ static int print_addresses(sd_bus *bus, const char *name, const char *prefix, co
                 if (r < 0)
                         return bus_log_parse_error(r);
 
-                printf("%s%s\n", prefix, inet_ntop(family, a, buffer, sizeof(buffer)));
+                fputs(prefix, stdout);
+                fputs(inet_ntop(family, a, buffer, sizeof(buffer)), stdout);
+                if (family == AF_INET6 && ifi > 0)
+                        printf("%%%i", ifi);
+                fputc('\n', stdout);
 
                 r = sd_bus_message_exit_container(reply);
                 if (r < 0)
@@ -275,11 +280,15 @@ typedef struct MachineStatusInfo {
         char *root_directory;
         pid_t leader;
         usec_t timestamp;
+        int *netif;
+        unsigned n_netif;
 } MachineStatusInfo;
 
 static void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
         char since2[FORMAT_TIMESTAMP_MAX], *s2;
+        int ifi = -1;
+
         assert(i);
 
         fputs(strna(i->name), stdout);
@@ -322,7 +331,30 @@ static void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
         if (i->root_directory)
                 printf("\t    Root: %s\n", i->root_directory);
 
-        print_addresses(bus, i->name,
+        if (i->n_netif > 0) {
+                unsigned c;
+
+                fputs("\t   Iface:", stdout);
+
+                for (c = 0; c < i->n_netif; c++) {
+                        char name[IF_NAMESIZE+1] = "";
+
+                        if (if_indextoname(i->netif[c], name)) {
+                                fputc(' ', stdout);
+                                fputs(name, stdout);
+
+                                if (ifi < 0)
+                                        ifi = i->netif[c];
+                                else
+                                        ifi = 0;
+                        } else
+                                printf(" %i", i->netif[c]);
+                }
+
+                fputc('\n', stdout);
+        }
+
+        print_addresses(bus, i->name, ifi,
                        "\t Address: ",
                        "\t          ");
 
@@ -334,17 +366,37 @@ static void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
         }
 }
 
+static int map_netif(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
+        MachineStatusInfo *i = userdata;
+        size_t l;
+        const void *v;
+        int r;
+
+        assert_cc(sizeof(int32_t) == sizeof(int));
+        r = sd_bus_message_read_array(m, SD_BUS_TYPE_INT32, &v, &l);
+        if (r < 0)
+                return r;
+
+        i->n_netif = l / sizeof(int32_t);
+        i->netif = memdup(v, l);
+        if (!i->netif)
+                return -ENOMEM;
+
+        return 0;
+}
+
 static int show_info(const char *verb, sd_bus *bus, const char *path, bool *new_line) {
 
         static const struct bus_properties_map map[]  = {
-                { "Name",          "s",  NULL,          offsetof(MachineStatusInfo, name) },
-                { "Class",         "s",  NULL,          offsetof(MachineStatusInfo, class) },
-                { "Service",       "s",  NULL,          offsetof(MachineStatusInfo, service) },
-                { "Unit",          "s",  NULL,          offsetof(MachineStatusInfo, unit) },
-                { "RootDirectory", "s",  NULL,          offsetof(MachineStatusInfo, root_directory) },
-                { "Leader",        "u",  NULL,          offsetof(MachineStatusInfo, leader) },
-                { "Timestamp",     "t",  NULL,          offsetof(MachineStatusInfo, timestamp) },
-                { "Id",            "ay", bus_map_id128, offsetof(MachineStatusInfo, id) },
+                { "Name",              "s",  NULL,          offsetof(MachineStatusInfo, name) },
+                { "Class",             "s",  NULL,          offsetof(MachineStatusInfo, class) },
+                { "Service",           "s",  NULL,          offsetof(MachineStatusInfo, service) },
+                { "Unit",              "s",  NULL,          offsetof(MachineStatusInfo, unit) },
+                { "RootDirectory",     "s",  NULL,          offsetof(MachineStatusInfo, root_directory) },
+                { "Leader",            "u",  NULL,          offsetof(MachineStatusInfo, leader) },
+                { "Timestamp",         "t",  NULL,          offsetof(MachineStatusInfo, timestamp) },
+                { "Id",                "ay", bus_map_id128, offsetof(MachineStatusInfo, id) },
+                { "NetworkInterfaces", "ai", map_netif,     0 },
                 {}
         };
 
@@ -375,6 +427,7 @@ static int show_info(const char *verb, sd_bus *bus, const char *path, bool *new_
         free(info.service);
         free(info.unit);
         free(info.root_directory);
+        free(info.netif);
 
         return r;
 }

commit 5aa4bb6b5b0b9dcea524d56cf8664b892a5a976a
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jul 10 22:48:30 2014 +0200

    nspawn: register external network interface with machined

diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index edad1cb..bad93a5 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -1388,7 +1388,7 @@ static int drop_capabilities(void) {
         return capability_bounding_set_drop(~arg_retain, false);
 }
 
-static int register_machine(pid_t pid) {
+static int register_machine(pid_t pid, int local_ifindex) {
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_bus_unref_ sd_bus *bus = NULL;
         int r;
@@ -1408,16 +1408,17 @@ static int register_machine(pid_t pid) {
                                 "org.freedesktop.machine1",
                                 "/org/freedesktop/machine1",
                                 "org.freedesktop.machine1.Manager",
-                                "RegisterMachine",
+                                "RegisterMachineWithNetwork",
                                 &error,
                                 NULL,
-                                "sayssus",
+                                "sayssusai",
                                 arg_machine,
                                 SD_BUS_MESSAGE_APPEND_ID128(arg_uuid),
                                 "nspawn",
                                 "container",
                                 (uint32_t) pid,
-                                strempty(arg_directory));
+                                strempty(arg_directory),
+                                local_ifindex > 0 ? 1 : 0, local_ifindex);
         } else {
                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
 
@@ -1427,7 +1428,7 @@ static int register_machine(pid_t pid) {
                                 "org.freedesktop.machine1",
                                 "/org/freedesktop/machine1",
                                 "org.freedesktop.machine1.Manager",
-                                "CreateMachine");
+                                "CreateMachineWithNetwork");
                 if (r < 0) {
                         log_error("Failed to create message: %s", strerror(-r));
                         return r;
@@ -1435,13 +1436,14 @@ static int register_machine(pid_t pid) {
 
                 r = sd_bus_message_append(
                                 m,
-                                "sayssus",
+                                "sayssusai",
                                 arg_machine,
                                 SD_BUS_MESSAGE_APPEND_ID128(arg_uuid),
                                 "nspawn",
                                 "container",
                                 (uint32_t) pid,
-                                strempty(arg_directory));
+                                strempty(arg_directory),
+                                local_ifindex > 0 ? 1 : 0, local_ifindex);
                 if (r < 0) {
                         log_error("Failed to append message arguments: %s", strerror(-r));
                         return r;
@@ -1644,11 +1646,11 @@ static int get_mac(struct ether_addr *mac) {
         return 0;
 }
 
-static int setup_veth(pid_t pid, char iface_name[IFNAMSIZ]) {
+static int setup_veth(pid_t pid, char iface_name[IFNAMSIZ], int *ifi) {
         _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
         _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
         struct ether_addr mac;
-        int r;
+        int r, i;
 
         if (!arg_private_network)
                 return 0;
@@ -1748,10 +1750,18 @@ static int setup_veth(pid_t pid, char iface_name[IFNAMSIZ]) {
                 return r;
         }
 
+        i = (int) if_nametoindex(iface_name);
+        if (i <= 0) {
+                log_error("Failed to resolve interface %s: %m", iface_name);
+                return -errno;
+        }
+
+        *ifi = i;
+
         return 0;
 }
 
-static int setup_bridge(const char veth_name[]) {
+static int setup_bridge(const char veth_name[], int *ifi) {
         _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
         _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
         int r, bridge;
@@ -1771,6 +1781,8 @@ static int setup_bridge(const char veth_name[]) {
                 return -errno;
         }
 
+        *ifi = bridge;
+
         r = sd_rtnl_open(&rtnl, 0);
         if (r < 0) {
                 log_error("Failed to connect to netlink: %s", strerror(-r));
@@ -3410,19 +3422,17 @@ int main(int argc, char *argv[]) {
                 eventfds[1] = safe_close(eventfds[1]);
 
                 if (r >= 0) {
-                        r = register_machine(pid);
-                        if (r < 0)
-                                goto finish;
+                        int ifi = 0;
 
                         r = move_network_interfaces(pid);
                         if (r < 0)
                                 goto finish;
 
-                        r = setup_veth(pid, veth_name);
+                        r = setup_veth(pid, veth_name, &ifi);
                         if (r < 0)
                                 goto finish;
 
-                        r = setup_bridge(veth_name);
+                        r = setup_bridge(veth_name, &ifi);
                         if (r < 0)
                                 goto finish;
 
@@ -3430,6 +3440,10 @@ int main(int argc, char *argv[]) {
                         if (r < 0)
                                 goto finish;
 
+                        r = register_machine(pid, ifi);
+                        if (r < 0)
+                                goto finish;
+
                         /* Block SIGCHLD here, before notifying child.
                          * process_pty() will handle it with the other signals. */
                         r = sigprocmask(SIG_BLOCK, &mask_chld, NULL);

commit 9b5ed6feda08290edce3bf916fa7362733dd30ea
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jul 10 22:47:55 2014 +0200

    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 3741485..72e0a70 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 cf38e3f..0ed18d7 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 fa9262d..5c63665 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 a041444..1b9449a 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),



More information about the systemd-commits mailing list