]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
network: stop recording saved physical net devices
authorChristian Brauner <christian.brauner@ubuntu.com>
Fri, 1 Sep 2017 14:44:46 +0000 (16:44 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Fri, 1 Sep 2017 19:36:50 +0000 (21:36 +0200)
liblxc will now correctly log any network device names and ifindeces in their
respective network namespaces. So there's no need to record physical network
devices any more. This spares us heap allocations and memory we need to have
lying around til the container is shutdown.

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

index 211f5d314ef88f4fe8a112d65ee57e17de1ec21b..8b2be8da0618e8b983d0706384d1a09fc7951658 100644 (file)
@@ -3502,17 +3502,6 @@ int lxc_clear_hooks(struct lxc_conf *c, const char *key)
        return 0;
 }
 
-static void lxc_clear_saved_nics(struct lxc_conf *conf)
-{
-       int i;
-
-       if (!conf->saved_nics)
-               return;
-       for (i=0; i < conf->num_savednics; i++)
-               free(conf->saved_nics[i].orig_name);
-       free(conf->saved_nics);
-}
-
 static inline void lxc_clear_aliens(struct lxc_conf *conf)
 {
        struct lxc_list *it,*next;
@@ -3567,7 +3556,6 @@ void lxc_conf_free(struct lxc_conf *conf)
        lxc_clear_cgroups(conf, "lxc.cgroup");
        lxc_clear_hooks(conf, "lxc.hook");
        lxc_clear_mount_entries(conf);
-       lxc_clear_saved_nics(conf);
        lxc_clear_idmaps(conf);
        lxc_clear_groups(conf);
        lxc_clear_includes(conf);
index bd525a2bee23892c41b63e699d4f994ac2efd5b9..7c38d93badfa343e9025b3ac1124dc2ab0fa72c4 100644 (file)
@@ -244,8 +244,6 @@ struct lxc_conf {
        struct lxc_list cgroup;
        struct lxc_list id_map;
        struct lxc_list network;
-       struct saved_nic *saved_nics;
-       int num_savednics;
        int auto_mounts;
        struct lxc_list mount_list;
        struct lxc_list caps;
index b3ae08b6826ef493167d569f4277328aaceae25e..02924fa93870801ae889489443ac148918398c11 100644 (file)
@@ -294,6 +294,10 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
                        break;
                case LXC_NET_PHYS:
                        TRACE("type: phys");
+                       if (netdev->priv.phys_attr.ifindex > 0) {
+                               TRACE("host side ifindex for phys device: %d",
+                                     netdev->priv.phys_attr.ifindex);
+                       }
                        break;
                case LXC_NET_EMPTY:
                        TRACE("type: empty");
index ef3070354cadd4ccd8a2c0d6e042b9a521ad7b6c..85b25961edb25f9aeaa9552de26e96386f62abe1 100644 (file)
@@ -2305,7 +2305,7 @@ bool lxc_delete_network_unpriv(struct lxc_handler *handler)
        char netns_path[6 + LXC_NUMSTRLEN64 + 4 + LXC_NUMSTRLEN64 + 1];
        bool deleted_all = true;
 
-       if (!am_unpriv())
+       if (handler->root)
                return true;
 
        *netns_path = '\0';
@@ -2374,13 +2374,10 @@ bool lxc_delete_network_unpriv(struct lxc_handler *handler)
 
 int lxc_create_network_priv(struct lxc_handler *handler)
 {
-       bool am_root;
        struct lxc_list *iterator;
        struct lxc_list *network = &handler->conf->network;
 
-       /* We need to be root. */
-       am_root = (getuid() == 0);
-       if (!am_root)
+       if (!handler->root)
                return 0;
 
        lxc_list_for_each(iterator, network) {
@@ -2482,7 +2479,7 @@ bool lxc_delete_network_priv(struct lxc_handler *handler)
        struct lxc_list *network = &handler->conf->network;
        bool deleted_all = true;
 
-       if (am_unpriv())
+       if (!handler->root)
                return true;
 
        lxc_list_for_each(iterator, network) {
@@ -2499,12 +2496,12 @@ bool lxc_delete_network_priv(struct lxc_handler *handler)
                        ret = lxc_netdev_rename_by_index(netdev->ifindex, netdev->link);
                        if (ret < 0)
                                WARN("Failed to rename interface with index %d "
-                                    "to its initial name \"%s\"",
-                                    netdev->ifindex, netdev->link);
+                                    "from \"%s\" to its initial name \"%s\"",
+                                    netdev->ifindex, netdev->name, netdev->link);
                        else
                                TRACE("Renamed interface with index %d to its "
-                                     "initial name \"%s\"",
-                                     netdev->ifindex, netdev->link);
+                                     "from \"%s\" to its initial name \"%s\"",
+                                     netdev->ifindex, netdev->name, netdev->link);
                        continue;
                }
 
@@ -2600,51 +2597,69 @@ int lxc_requests_empty_network(struct lxc_handler *handler)
 }
 
 /* try to move physical nics to the init netns */
-void lxc_restore_phys_nics_to_netns(int netnsfd, struct lxc_conf *conf)
+int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler)
 {
        int ret;
-       int i, oldfd;
+       int oldfd;
        char ifname[IFNAMSIZ];
+       struct lxc_list *iterator;
+       int netnsfd = handler->netnsfd;
+       struct lxc_conf *conf = handler->conf;
 
-       if (netnsfd < 0 || conf->num_savednics == 0)
-               return;
+       /* We need CAP_NET_ADMIN in the parent namespace in order to setns() to
+        * the parent network namespace. We won't have this capability if we are
+        * unprivileged.
+        */
+       if (!handler->root)
+               return 0;
 
-       INFO("Trying to restore network device names in original namespace for "
-            "%d network devices", conf->num_savednics);
+       TRACE("Moving physical network devices back to parent network namespace");
 
        oldfd = lxc_preserve_ns(getpid(), "net");
        if (oldfd < 0) {
                SYSERROR("Failed to preserve network namespace");
-               return;
+               return -1;
        }
 
-       ret = setns(netnsfd, 0);
+       ret = setns(netnsfd, CLONE_NEWNET);
        if (ret < 0) {
                SYSERROR("Failed to enter network namespace");
                close(oldfd);
-               return;
+               return -1;
        }
 
-       for (i = 0; i < conf->num_savednics; i++) {
-               struct saved_nic *s = &conf->saved_nics[i];
+       lxc_list_for_each(iterator, &conf->network) {
+               struct lxc_netdev *netdev = iterator->elem;
 
-               /* retrieve the name of the interface */
-               if (!if_indextoname(s->ifindex, ifname)) {
+               if (netdev->type != LXC_NET_PHYS)
+                       continue;
+
+               /* Retrieve the name of the interface in the container's network
+                * namespace.
+                */
+               if (!if_indextoname(netdev->ifindex, ifname)) {
                        WARN("No interface corresponding to ifindex %d",
-                            s->ifindex);
+                            netdev->ifindex);
                        continue;
                }
-               if (lxc_netdev_move_by_name(ifname, 1, s->orig_name))
+
+               ret = lxc_netdev_move_by_name(ifname, 1, netdev->link);
+               if (ret < 0)
                        WARN("Error moving network device \"%s\" back to "
                             "network namespace", ifname);
-               free(s->orig_name);
+               else
+                       TRACE("Moved network device \"%s\" back to network "
+                             "namespace", ifname);
        }
-       conf->num_savednics = 0;
 
-       ret = setns(oldfd, 0);
-       if (ret < 0)
-               SYSERROR("Failed to enter network namespace");
+       ret = setns(oldfd, CLONE_NEWNET);
        close(oldfd);
+       if (ret < 0) {
+               SYSERROR("Failed to enter network namespace");
+               return -1;
+       }
+
+       return 0;
 }
 
 static int setup_hw_addr(char *hwaddr, const char *ifname)
index 7c89c52158795fd33742348ffe7ea4e97c0aa623..5db84058e8d62aec2b81ab048e9703aac773e5f2 100644 (file)
@@ -175,11 +175,6 @@ struct lxc_netdev {
        char *downscript;
 };
 
-struct saved_nic {
-       int ifindex;
-       char *orig_name;
-};
-
 /* Convert a string mac address to a socket structure. */
 extern int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr);
 
@@ -277,7 +272,7 @@ extern int lxc_find_gateway_addresses(struct lxc_handler *handler);
 extern int lxc_create_network_unpriv(const char *lxcpath, char *lxcname,
                                     struct lxc_list *network, pid_t pid);
 extern int lxc_requests_empty_network(struct lxc_handler *handler);
-extern void lxc_restore_phys_nics_to_netns(int netnsfd, struct lxc_conf *conf);
+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);
 
index 131f43c22239cbed43c9323d8a432f60757b9e25..d077ff4b09db8344677747a65f4098fd3eebb1ad 100644 (file)
@@ -1097,36 +1097,6 @@ out_error:
        return -1;
 }
 
-static int save_phys_nics(struct lxc_conf *conf)
-{
-       struct lxc_list *iterator;
-       int am_root = (getuid() == 0);
-
-       if (!am_root)
-               return 0;
-
-       lxc_list_for_each(iterator, &conf->network) {
-               struct lxc_netdev *netdev = iterator->elem;
-
-               if (netdev->type != LXC_NET_PHYS)
-                       continue;
-               conf->saved_nics = realloc(conf->saved_nics,
-                               (conf->num_savednics+1)*sizeof(struct saved_nic));
-               if (!conf->saved_nics)
-                       return -1;
-               conf->saved_nics[conf->num_savednics].ifindex = netdev->ifindex;
-               conf->saved_nics[conf->num_savednics].orig_name = strdup(netdev->link);
-               if (!conf->saved_nics[conf->num_savednics].orig_name)
-                       return -1;
-               INFO("Stored saved_nic #%d idx %d name %s.", conf->num_savednics,
-                       conf->saved_nics[conf->num_savednics].ifindex,
-                       conf->saved_nics[conf->num_savednics].orig_name);
-               conf->num_savednics++;
-       }
-
-       return 0;
-}
-
 static int lxc_network_recv_name_and_ifindex_from_child(struct lxc_handler *handler)
 {
        struct lxc_list *iterator, *network;
@@ -1294,11 +1264,6 @@ static int lxc_spawn(struct lxc_handler *handler)
                                return -1;
                        }
                }
-
-               if (save_phys_nics(handler->conf)) {
-                       ERROR("Failed to save physical nic info.");
-                       goto out_abort;
-               }
        }
 
        if (!cgroup_init(handler)) {
@@ -1618,8 +1583,10 @@ int __lxc_start(const char *name, struct lxc_handler *handler,
                }
        }
 
-       DEBUG("Pushing physical nics back to host namespace");
-       lxc_restore_phys_nics_to_netns(handler->netnsfd, handler->conf);
+       err = lxc_restore_phys_nics_to_netns(handler);
+       if (err < 0)
+               ERROR("Failed to move physical network devices back to parent "
+                     "network namespace");
 
        if (handler->pinfd >= 0) {
                close(handler->pinfd);