]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
network: remove netpipe
authorChristian Brauner <christian.brauner@ubuntu.com>
Fri, 1 Sep 2017 20:33:21 +0000 (22:33 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Mon, 4 Sep 2017 16:37:55 +0000 (18:37 +0200)
We use data_sock for all things we need to send around between parent and child
now. It doesn't make sense to have so many different pipes and sockets if one
will do just fine.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/network.c
src/lxc/network.h
src/lxc/start.c

index 68058850817542b1773f79ef4f3229ea82d6a937..78fe83c38f700399660386c4af952a5f552f184b 100644 (file)
@@ -45,6 +45,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
+#include "af_unix.h"
 #include "conf.h"
 #include "config.h"
 #include "log.h"
@@ -2963,3 +2964,65 @@ int lxc_setup_network_in_child_namespaces(const struct lxc_conf *conf,
 
        return 0;
 }
+
+int lxc_network_send_veth_names_to_child(struct lxc_handler *handler)
+{
+       struct lxc_list *iterator;
+       struct lxc_list *network = &handler->conf->network;
+       int data_sock = handler->data_sock[0];
+
+       if (handler->root)
+               return 0;
+
+       lxc_list_for_each(iterator, network) {
+               int ret;
+               struct lxc_netdev *netdev = iterator->elem;
+
+               if (netdev->type != LXC_NET_VETH)
+                       continue;
+
+               ret = lxc_abstract_unix_send_credential(data_sock, netdev->name,
+                                                       IFNAMSIZ);
+               if (ret < 0) {
+                       close(handler->data_sock[0]);
+                       close(handler->data_sock[1]);
+                       return -1;
+               } else {
+                       TRACE("Sent network device name \"%s\" to child",
+                             netdev->name);
+               }
+       }
+
+       return 0;
+}
+
+int lxc_network_recv_veth_names_from_parent(struct lxc_handler *handler)
+{
+       struct lxc_list *iterator;
+       struct lxc_list *network = &handler->conf->network;
+       int data_sock = handler->data_sock[1];
+
+       if (handler->root)
+               return 0;
+
+       lxc_list_for_each(iterator, network) {
+               int ret;
+               struct lxc_netdev *netdev = iterator->elem;
+
+               if (netdev->type != LXC_NET_VETH)
+                       continue;
+
+               ret = lxc_abstract_unix_rcv_credential(data_sock, netdev->name,
+                                                      IFNAMSIZ);
+               if (ret < 0) {
+                       close(handler->data_sock[0]);
+                       close(handler->data_sock[1]);
+                       return -1;
+               } else {
+                       TRACE("Received network device name \"%s\" from parent",
+                             netdev->name);
+               }
+       }
+
+       return 0;
+}
index 9badf14b87ee059bb7dabc32929e122eaf080625..5dd48fb2ad38c2f2703a9385649167534d40c41f 100644 (file)
@@ -305,5 +305,7 @@ extern int lxc_requests_empty_network(struct lxc_handler *handler);
 extern int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler);
 extern int lxc_setup_network_in_child_namespaces(const struct lxc_conf *conf,
                                                 struct lxc_list *network);
+extern int lxc_network_send_veth_names_to_child(struct lxc_handler *handler);
+extern int lxc_network_recv_veth_names_from_parent(struct lxc_handler *handler);
 
 #endif /* __LXC_NETWORK_H */
index 116b1ebd84fa21bf16dabc50a0917bff8269eec2..a6f58c634b6f5b44326d559094ce85442c117c87 100644 (file)
@@ -854,48 +854,6 @@ static int must_drop_cap_sys_boot(struct lxc_conf *conf)
        return 0;
 }
 
-/* netpipe is used in the unprivileged case to transfer the ifindexes from
- * parent to child
- */
-static int netpipe = -1;
-
-static inline int count_veths(struct lxc_list *network)
-{
-       struct lxc_list *iterator;
-       struct lxc_netdev *netdev;
-       int count = 0;
-
-       lxc_list_for_each(iterator, network) {
-               netdev = iterator->elem;
-               if (netdev->type != LXC_NET_VETH)
-                       continue;
-               count++;
-       }
-       return count;
-}
-
-static int read_unpriv_netifindex(struct lxc_list *network)
-{
-       struct lxc_list *iterator;
-       struct lxc_netdev *netdev;
-
-       if (netpipe == -1)
-               return 0;
-
-       lxc_list_for_each(iterator, network) {
-               netdev = iterator->elem;
-               if (netdev->type != LXC_NET_VETH)
-                       continue;
-
-               if (read(netpipe, netdev->name, IFNAMSIZ) != IFNAMSIZ) {
-                       close(netpipe);
-                       return -1;
-               }
-       }
-       close(netpipe);
-       return 0;
-}
-
 static int do_start(void *data)
 {
        struct lxc_list *iterator;
@@ -948,8 +906,10 @@ static int do_start(void *data)
        if (lxc_sync_barrier_parent(handler, LXC_SYNC_CONFIGURE))
                return -1;
 
-       if (read_unpriv_netifindex(&handler->conf->network) < 0)
+       if (lxc_network_recv_veth_names_from_parent(handler) < 0) {
+               ERROR("Failed to receive veth names from parent");
                goto out_warn_father;
+       }
 
        /* If we are in a new user namespace, become root there to have
         * privilege over our namespace.
@@ -1278,15 +1238,14 @@ void resolve_clone_flags(struct lxc_handler *handler)
  */
 static int lxc_spawn(struct lxc_handler *handler)
 {
-       int i, flags, nveths, ret;
+       int i, flags, ret;
        const char *name = handler->name;
        bool wants_to_map_ids;
-       int netpipepair[2], saved_ns_fd[LXC_NS_MAX];
+       int saved_ns_fd[LXC_NS_MAX];
        struct lxc_list *id_map;
        int failed_before_rename = 0, preserve_mask = 0;
        bool cgroups_connected = false;
 
-       netpipe = -1;
        id_map = &handler->conf->id_map;
        wants_to_map_ids = !lxc_list_empty(id_map);
 
@@ -1359,15 +1318,6 @@ static int lxc_spawn(struct lxc_handler *handler)
        if (attach_ns(handler->conf->inherit_ns_fd) < 0)
                goto out_delete_net;
 
-       if (!handler->root && (nveths = count_veths(&handler->conf->network))) {
-               if (pipe(netpipepair) < 0) {
-                       SYSERROR("Failed to create pipe.");
-                       goto out_delete_net;
-               }
-               /* Store netpipe in the global var for do_start's use. */
-               netpipe = netpipepair[0];
-       }
-
        /* Create a process in a new set of namespaces. */
        flags = handler->clone_flags;
        if (handler->clone_flags & CLONE_NEWUSER) {
@@ -1459,21 +1409,9 @@ static int lxc_spawn(struct lxc_handler *handler)
                }
        }
 
-       if (netpipe != -1) {
-               struct lxc_list *iterator;
-               struct lxc_netdev *netdev;
-
-               close(netpipe);
-               lxc_list_for_each(iterator, &handler->conf->network) {
-                       netdev = iterator->elem;
-                       if (netdev->type != LXC_NET_VETH)
-                               continue;
-                       if (write(netpipepair[1], netdev->name, IFNAMSIZ) != IFNAMSIZ) {
-                               ERROR("Error writing veth name to container.");
-                               goto out_delete_net;
-                       }
-               }
-               close(netpipepair[1]);
+       if (lxc_network_send_veth_names_to_child(handler) < 0) {
+               ERROR("Failed to send veth names to child");
+               goto out_delete_net;
        }
 
        /* Tell the child to continue its initialization. We'll get