The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxc/pull/1768

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Signed-off-by: Christian Brauner <[email protected]>
From 06516dc1e0a3286a3adddcd4e9aaf0d39f44ac57 Mon Sep 17 00:00:00 2001
From: Christian Brauner <[email protected]>
Date: Thu, 24 Aug 2017 15:31:38 +0200
Subject: [PATCH 1/4] openvswitch: delete ports intelligently

So far, when creating veth devices attached to openvswitch bridges we used to
fork() off a thread on container startup. This thread was kept around until the
container shut down. I have no good explanation why we did it that why but it's
certainly not necessary. Instead, let's fork() off the thread on container
shutdown to delete the veth.

Signed-off-by: Christian Brauner <[email protected]>
---
 src/lxc/conf.c         | 22 ++++++++++--
 src/lxc/lxc_user_nic.c |  2 +-
 src/lxc/network.c      | 93 +++++++++++++++++++++++++-------------------------
 src/lxc/network.h      |  5 ++-
 4 files changed, 72 insertions(+), 50 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index c5609ec4e..8b8ae9109 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -2757,7 +2757,7 @@ static int instantiate_veth(struct lxc_handler *handler, 
struct lxc_netdev *netd
        }
 
        if (netdev->link) {
-               err = lxc_bridge_attach(handler->lxcpath, handler->name, 
netdev->link, veth1);
+               err = lxc_bridge_attach(netdev->link, veth1);
                if (err) {
                        ERROR("failed to attach \"%s\" to bridge \"%s\": %s",
                              veth1, netdev->link, strerror(-err));
@@ -3135,11 +3135,20 @@ bool lxc_delete_network(struct lxc_handler *handler)
                        char *hostveth;
                        if (netdev->priv.veth_attr.pair) {
                                hostveth = netdev->priv.veth_attr.pair;
+
                                ret = lxc_netdev_delete_by_name(hostveth);
                                if (ret < 0)
                                        WARN("Failed to remove interface \"%s\" 
from host: %s.", hostveth, strerror(-ret));
                                else
                                        INFO("Removed interface \"%s\" from 
host.", hostveth);
+
+                               if (is_ovs_bridge(netdev->link)) {
+                                       ret = lxc_ovs_delete_port(netdev->link, 
hostveth);
+                                       if (ret < 0)
+                                               WARN("Failed to remove port 
\"%s\" from openvswitch bridge \"%s\"", hostveth, netdev->link);
+                                       else
+                                               INFO("Removed port \"%s\" from 
openvswitch bridge \"%s\"", hostveth, netdev->link);
+                               }
                        } else if (strlen(netdev->priv.veth_attr.veth1) > 0) {
                                hostveth = netdev->priv.veth_attr.veth1;
                                ret = lxc_netdev_delete_by_name(hostveth);
@@ -3147,7 +3156,16 @@ bool lxc_delete_network(struct lxc_handler *handler)
                                        WARN("Failed to remove \"%s\" from 
host: %s.", hostveth, strerror(-ret));
                                } else {
                                        INFO("Removed interface \"%s\" from 
host.", hostveth);
-                                       memset((void 
*)&netdev->priv.veth_attr.veth1, 0, sizeof(netdev->priv.veth_attr.veth1));
+
+                                       if (is_ovs_bridge(netdev->link)) {
+                                               ret = 
lxc_ovs_delete_port(netdev->link, hostveth);
+                                               if (ret < 0) {
+                                                       WARN("Failed to remove 
port \"%s\" from openvswitch bridge \"%s\"", hostveth, netdev->link);
+                                               } else {
+                                                       INFO("Removed port 
\"%s\" from openvswitch bridge \"%s\"", hostveth, netdev->link);
+                                                       memset((void 
*)&netdev->priv.veth_attr.veth1, 0, sizeof(netdev->priv.veth_attr.veth1));
+                                               }
+                                       }
                                }
                        }
                }
diff --git a/src/lxc/lxc_user_nic.c b/src/lxc/lxc_user_nic.c
index c93b4cc70..96af8363b 100644
--- a/src/lxc/lxc_user_nic.c
+++ b/src/lxc/lxc_user_nic.c
@@ -483,7 +483,7 @@ static bool create_nic(char *nic, char *br, int pid, char 
**cnic)
                }
 
                /* attach veth1 to bridge */
-               ret = lxc_bridge_attach(lxcpath, lxcname, br, veth1buf);
+               ret = lxc_bridge_attach(br, veth1buf);
                if (ret < 0) {
                        usernic_error("Error attaching %s to %s.\n", veth1buf, 
br);
                        goto out_del;
diff --git a/src/lxc/network.c b/src/lxc/network.c
index 84fa9d5a5..6685792b6 100644
--- a/src/lxc/network.c
+++ b/src/lxc/network.c
@@ -1395,7 +1395,7 @@ int lxc_ipv6_dest_add(int ifindex, struct in6_addr *dest)
        return ip_route_dest_add(AF_INET6, ifindex, dest);
 }
 
-static bool is_ovs_bridge(const char *bridge)
+bool is_ovs_bridge(const char *bridge)
 {
        char brdirname[22 + IFNAMSIZ + 1] = {0};
        struct stat sb;
@@ -1406,70 +1406,71 @@ static bool is_ovs_bridge(const char *bridge)
        return false;
 }
 
+struct ovs_veth_args {
+       const char *bridge;
+       const char *nic;
+};
+
 /* Called from a background thread - when nic goes away, remove it from the
  * bridge.
  */
-static void ovs_cleanup_nic(const char *lxcpath, const char *name,
-                           const char *bridge, const char *nic)
+static int lxc_ovs_delete_port_exec(void *data)
 {
-       int ret;
+       struct ovs_veth_args *args = data;
 
-       ret = lxc_check_inherited(NULL, true, &(int){-1}, 1);
-       if (ret < 0)
-               return;
+       execlp("ovs-vsctl", "ovs-vsctl", "del-port", args->bridge, args->nic,
+              (char *)NULL);
+       return -1;
+}
 
-       TRACE("Registering cleanup thread to remove nic \"%s\" from "
-             "openvswitch bridge \"%s\"", nic, bridge);
+int lxc_ovs_delete_port(const char *bridge, const char *nic)
+{
+       int ret;
+       char cmd_output[MAXPATHLEN];
+       struct ovs_veth_args args;
 
-       ret = lxc_wait(name, "STOPPED", -1, lxcpath);
+       args.bridge = bridge;
+       args.nic = nic;
+       ret = run_command(cmd_output, sizeof(cmd_output),
+                         lxc_ovs_delete_port_exec, (void *)&args);
        if (ret < 0) {
-               ERROR("Failed to register cleanup thread to remove nic \"%s\" "
-                     "from  openvswitch bridge \"%s\"", nic, bridge);
-               return;
+               ERROR("Failed to delete \"%s\" from openvswitch bridge \"%s\": "
+                     "%s", bridge, nic, cmd_output);
+               return -1;
        }
 
-       execlp("ovs-vsctl", "ovs-vsctl", "del-port", bridge, nic, (char *)NULL);
-       exit(EXIT_FAILURE);
+       return 0;
 }
 
-static int attach_to_ovs_bridge(const char *lxcpath, const char *name, const 
char *bridge, const char *nic)
+static int lxc_ovs_attach_bridge_exec(void *data)
 {
-       pid_t pid;
-       char *cmd;
-       int ret;
+       struct ovs_veth_args *args = data;
 
-       cmd = on_path("ovs-vsctl", NULL);
-       if (!cmd)
-               return -1;
-       free(cmd);
+       execlp("ovs-vsctl", "ovs-vsctl", "add-port", args->bridge, args->nic,
+              (char *)NULL);
+       return -1;
+}
 
-       pid = fork();
-       if (pid < 0)
+static int lxc_ovs_attach_bridge(const char *bridge, const char *nic)
+{
+       int ret;
+       char cmd_output[MAXPATHLEN];
+       struct ovs_veth_args args;
+
+       args.bridge = bridge;
+       args.nic = nic;
+       ret = run_command(cmd_output, sizeof(cmd_output),
+                         lxc_ovs_attach_bridge_exec, (void *)&args);
+       if (ret < 0) {
+               ERROR("Failed to attach \"%s\" to openvswitch bridge \"%s\": 
%s",
+                     bridge, nic, cmd_output);
                return -1;
-       if (pid > 0) {
-               ret = wait_for_pid(pid);
-               if (ret < 0)
-                       return ret;
-               pid = fork();
-               if (pid < 0)
-                       return -1;  // how to properly recover?
-               if (pid > 0)
-                       return 0;
-               ovs_cleanup_nic(lxcpath, name, bridge, nic);
-               exit(0);
        }
 
-       if (execlp("ovs-vsctl", "ovs-vsctl", "add-port", bridge, nic, (char 
*)NULL))
-               exit(1);
-       // not reached
-       exit(1);
+       return 0;
 }
 
-/*
- * There is a lxc_bridge_attach, but no need of a bridge detach
- * as automatically done by kernel when a netdev is deleted.
- */
-int lxc_bridge_attach(const char *lxcpath, const char *name, const char 
*bridge, const char *ifname)
+int lxc_bridge_attach(const char *bridge, const char *ifname)
 {
        int fd, index, err;
        struct ifreq ifr;
@@ -1482,7 +1483,7 @@ int lxc_bridge_attach(const char *lxcpath, const char 
*name, const char *bridge,
                return -EINVAL;
 
        if (is_ovs_bridge(bridge))
-               return attach_to_ovs_bridge(lxcpath, name, bridge, ifname);
+               return lxc_ovs_attach_bridge(bridge, ifname);
 
        fd = socket(AF_INET, SOCK_STREAM, 0);
        if (fd < 0)
diff --git a/src/lxc/network.h b/src/lxc/network.h
index aa19dae33..b9dec641b 100644
--- a/src/lxc/network.h
+++ b/src/lxc/network.h
@@ -109,7 +109,10 @@ extern int lxc_ipv6_gateway_add(int ifindex, struct 
in6_addr *gw);
 /*
  * Attach an interface to the bridge
  */
-extern int lxc_bridge_attach(const char *lxcpath, const char *name, const char 
*bridge, const char *ifname);
+extern int lxc_bridge_attach(const char *bridge, const char *ifname);
+extern int lxc_ovs_delete_port(const char *bridge, const char *nic);
+
+extern bool is_ovs_bridge(const char *bridge);
 
 /*
  * Create default gateway

From 26c91f8b196fa1e27fdafbf77484025ec80fadfc Mon Sep 17 00:00:00 2001
From: Christian Brauner <[email protected]>
Date: Thu, 24 Aug 2017 16:10:30 +0200
Subject: [PATCH 2/4] conf: refactor network deletion

I'm ashamed at how aweful my previous code was.

Signed-off-by: Christian Brauner <[email protected]>
---
 src/lxc/conf.c | 134 +++++++++++++++++++++++++++++----------------------------
 1 file changed, 69 insertions(+), 65 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 8b8ae9109..a77b3df9e 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -3083,92 +3083,96 @@ int lxc_create_network(struct lxc_handler *handler)
 bool lxc_delete_network(struct lxc_handler *handler)
 {
        int ret;
-       struct lxc_list *network = &handler->conf->network;
        struct lxc_list *iterator;
-       struct lxc_netdev *netdev;
+       struct lxc_list *network = &handler->conf->network;
        bool deleted_all = true;
 
        lxc_list_for_each(iterator, network) {
-               netdev = iterator->elem;
+               char *hostveth = NULL;
+               struct lxc_netdev *netdev = iterator->elem;
+
+               /* We can only delete devices whose ifindex we have. If we don't
+                * have the index it means that we didn't create it.
+                */
+               if (!netdev->ifindex)
+                       continue;
 
-               if (netdev->ifindex != 0 && netdev->type == LXC_NET_PHYS) {
-                       if (lxc_netdev_rename_by_index(netdev->ifindex, 
netdev->link))
+               if (netdev->type == LXC_NET_PHYS) {
+                       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\".",
+                                    "to its initial name \"%s\"",
                                     netdev->ifindex, netdev->link);
+                       else
+                               TRACE("Renamed interface with index %d to its "
+                                     "initial name \"%s\"",
+                                     netdev->ifindex, netdev->link);
                        continue;
                }
 
-               if (netdev_deconf[netdev->type](handler, netdev)) {
-                       WARN("Failed to destroy netdev");
-               }
+               ret = netdev_deconf[netdev->type](handler, netdev);
+               if (ret < 0)
+                       WARN("Failed to deconfigure network device");
 
                /* Recent kernel remove the virtual interfaces when the network
                 * namespace is destroyed but in case we did not move the
                 * interface to the network namespace, we have to destroy it
                 */
-               if (netdev->ifindex != 0) {
-                       ret = lxc_netdev_delete_by_index(netdev->ifindex);
-                       if (-ret == ENODEV) {
-                               INFO("Interface \"%s\" with index %d already "
-                                    "deleted or existing in different network "
-                                    "namespace.",
-                                    netdev->name ? netdev->name : "(null)",
-                                    netdev->ifindex);
-                       } else if (ret < 0) {
-                               deleted_all = false;
-                               WARN("Failed to remove interface \"%s\" with "
-                                    "index %d: %s.",
-                                    netdev->name ? netdev->name : "(null)",
-                                    netdev->ifindex, strerror(-ret));
-                       } else {
-                               INFO("Removed interface \"%s\" with index %d.",
-                                    netdev->name ? netdev->name : "(null)",
-                                    netdev->ifindex);
-                       }
+               ret = lxc_netdev_delete_by_index(netdev->ifindex);
+               if (-ret == ENODEV) {
+                       INFO("Interface \"%s\" with index %d already deleted "
+                            "or existing in different network namespace",
+                            netdev->name ? netdev->name : "(null)", 
netdev->ifindex);
+               } else if (ret < 0) {
+                       deleted_all = false;
+                       WARN("Failed to remove interface \"%s\" with index %d: "
+                            "%s", netdev->name ? netdev->name : "(null)",
+                            netdev->ifindex, strerror(-ret));
+                       continue;
                }
+               INFO("Removed interface \"%s\" with index %d",
+                    netdev->name ? netdev->name : "(null)", netdev->ifindex);
+
+               if (netdev->type != LXC_NET_VETH)
+                       continue;
+
+               if (am_unpriv())
+                       continue;
 
                /* Explicitly delete host veth device to prevent lingering
                 * devices. We had issues in LXD around this.
                 */
-               if (netdev->ifindex != 0 && netdev->type == LXC_NET_VETH && 
!am_unpriv()) {
-                       char *hostveth;
-                       if (netdev->priv.veth_attr.pair) {
-                               hostveth = netdev->priv.veth_attr.pair;
-
-                               ret = lxc_netdev_delete_by_name(hostveth);
-                               if (ret < 0)
-                                       WARN("Failed to remove interface \"%s\" 
from host: %s.", hostveth, strerror(-ret));
-                               else
-                                       INFO("Removed interface \"%s\" from 
host.", hostveth);
-
-                               if (is_ovs_bridge(netdev->link)) {
-                                       ret = lxc_ovs_delete_port(netdev->link, 
hostveth);
-                                       if (ret < 0)
-                                               WARN("Failed to remove port 
\"%s\" from openvswitch bridge \"%s\"", hostveth, netdev->link);
-                                       else
-                                               INFO("Removed port \"%s\" from 
openvswitch bridge \"%s\"", hostveth, netdev->link);
-                               }
-                       } else if (strlen(netdev->priv.veth_attr.veth1) > 0) {
-                               hostveth = netdev->priv.veth_attr.veth1;
-                               ret = lxc_netdev_delete_by_name(hostveth);
-                               if (ret < 0) {
-                                       WARN("Failed to remove \"%s\" from 
host: %s.", hostveth, strerror(-ret));
-                               } else {
-                                       INFO("Removed interface \"%s\" from 
host.", hostveth);
-
-                                       if (is_ovs_bridge(netdev->link)) {
-                                               ret = 
lxc_ovs_delete_port(netdev->link, hostveth);
-                                               if (ret < 0) {
-                                                       WARN("Failed to remove 
port \"%s\" from openvswitch bridge \"%s\"", hostveth, netdev->link);
-                                               } else {
-                                                       INFO("Removed port 
\"%s\" from openvswitch bridge \"%s\"", hostveth, netdev->link);
-                                                       memset((void 
*)&netdev->priv.veth_attr.veth1, 0, sizeof(netdev->priv.veth_attr.veth1));
-                                               }
-                                       }
-                               }
-                       }
+               if (netdev->priv.veth_attr.pair)
+                       hostveth = netdev->priv.veth_attr.pair;
+               else
+                       hostveth = netdev->priv.veth_attr.veth1;
+               if (*hostveth == '\0')
+                       continue;
+
+               ret = lxc_netdev_delete_by_name(hostveth);
+               if (ret < 0) {
+                       deleted_all = false;
+                       WARN("Failed to remove interface \"%s\" from \"%s\": 
%s",
+                            hostveth, netdev->link, strerror(-ret));
+                       continue;
+               }
+               INFO("Removed interface \"%s\" from \"%s\"", hostveth, 
netdev->link);
+
+               if (!is_ovs_bridge(netdev->link)) {
+                       netdev->priv.veth_attr.veth1[0] = '\0';
+                       continue;
                }
+
+               /* Delete the openvswitch port. */
+               ret = lxc_ovs_delete_port(netdev->link, hostveth);
+               if (ret < 0)
+                       WARN("Failed to remove port \"%s\" from openvswitch "
+                            "bridge \"%s\"", hostveth, netdev->link);
+               else
+                       INFO("Removed port \"%s\" from openvswitch bridge 
\"%s\"",
+                            hostveth, netdev->link);
+
+               netdev->priv.veth_attr.veth1[0] = '\0';
        }
 
        return deleted_all;

From 9790c1e2edc444089c4813776505cb0c8a9373c8 Mon Sep 17 00:00:00 2001
From: Christian Brauner <[email protected]>
Date: Fri, 25 Aug 2017 00:02:47 +0200
Subject: [PATCH 3/4] conf: do not check union on wrong net type

This will obviously not work.

Signed-off-by: Christian Brauner <[email protected]>
---
 src/lxc/conf.c | 25 ++-----------------------
 1 file changed, 2 insertions(+), 23 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index a77b3df9e..8a11ff345 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -3049,27 +3049,6 @@ int lxc_create_network(struct lxc_handler *handler)
 
                netdev = iterator->elem;
 
-               if (netdev->type != LXC_NET_MACVLAN && 
netdev->priv.macvlan_attr.mode) {
-                       ERROR("Invalid macvlan.mode for a non-macvlan netdev");
-                       return -1;
-               }
-
-               if (netdev->type != LXC_NET_VETH && 
netdev->priv.veth_attr.pair) {
-                       ERROR("Invalid veth pair for a non-veth netdev");
-                       return -1;
-               }
-
-               if (netdev->type != LXC_NET_VLAN && netdev->priv.vlan_attr.vid 
> 0) {
-                       ERROR("Invalid vlan.id for a non-macvlan netdev");
-                       return -1;
-               }
-
-               if (netdev->type < 0 || netdev->type > LXC_NET_MAXCONFTYPE) {
-                       ERROR("invalid network configuration type '%d'",
-                             netdev->type);
-                       return -1;
-               }
-
                if (netdev_conf[netdev->type](handler, netdev)) {
                        ERROR("failed to create netdev");
                        return -1;
@@ -3114,9 +3093,9 @@ bool lxc_delete_network(struct lxc_handler *handler)
                if (ret < 0)
                        WARN("Failed to deconfigure network device");
 
-               /* Recent kernel remove the virtual interfaces when the network
+               /* Recent kernels remove the virtual interfaces when the network
                 * namespace is destroyed but in case we did not move the
-                * interface to the network namespace, we have to destroy it
+                * interface to the network namespace, we have to destroy it.
                 */
                ret = lxc_netdev_delete_by_index(netdev->ifindex);
                if (-ret == ENODEV) {

From 67c407682fac3c68ccca3c52f5648162826c8a6a Mon Sep 17 00:00:00 2001
From: Christian Brauner <[email protected]>
Date: Fri, 25 Aug 2017 07:35:02 +0200
Subject: [PATCH 4/4] attach: non-functional changes

Signed-off-by: Christian Brauner <[email protected]>
---
 src/lxc/attach.c | 172 ++++++++++++++++++++++++++++++-------------------------
 src/lxc/attach.h |   8 ++-
 2 files changed, 100 insertions(+), 80 deletions(-)

diff --git a/src/lxc/attach.c b/src/lxc/attach.c
index 360dd6d8e..b66824f23 100644
--- a/src/lxc/attach.c
+++ b/src/lxc/attach.c
@@ -39,6 +39,8 @@
 #include <sys/syscall.h>
 #include <sys/wait.h>
 
+#include <lxc/lxccontainer.h>
+
 #if !HAVE_DECL_PR_CAPBSET_DROP
 #define PR_CAPBSET_DROP 24
 #endif
@@ -58,14 +60,12 @@
 #include "namespace.h"
 #include "utils.h"
 
-#include <lxc/lxccontainer.h>
-
 #if HAVE_SYS_PERSONALITY_H
 #include <sys/personality.h>
 #endif
 
 #ifndef SOCK_CLOEXEC
-#  define SOCK_CLOEXEC                02000000
+#define SOCK_CLOEXEC 02000000
 #endif
 
 #ifndef MS_REC
@@ -73,7 +73,7 @@
 #endif
 
 #ifndef MS_SLAVE
-#define MS_SLAVE (1<<19)
+#define MS_SLAVE (1 << 19)
 #endif
 
 lxc_log_define(lxc_attach, lxc);
@@ -118,7 +118,7 @@ static int lsm_openat(int procfd, pid_t pid, int on_exec)
 static int lsm_set_label_at(int lsm_labelfd, int on_exec, char *lsm_label)
 {
        int fret = -1;
-       const char* name;
+       const char *name;
        char *command = NULL;
 
        name = lsm_name();
@@ -136,7 +136,8 @@ static int lsm_set_label_at(int lsm_labelfd, int on_exec, 
char *lsm_label)
        if (strcmp(name, "AppArmor") == 0) {
                int size;
 
-               command = malloc(strlen(lsm_label) + strlen("changeprofile ") + 
1);
+               command =
+                   malloc(strlen(lsm_label) + strlen("changeprofile ") + 1);
                if (!command) {
                        SYSERROR("Failed to write apparmor profile.");
                        goto out;
@@ -178,12 +179,12 @@ static int lsm_set_label_at(int lsm_labelfd, int on_exec, 
char *lsm_label)
 #define __PROC_STATUS_LEN (5 + 21 + 7 + 1)
 static struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid)
 {
+       int ret;
+       bool found;
        FILE *proc_file;
        char proc_fn[__PROC_STATUS_LEN];
-       bool found;
-       int ret;
-       char *line = NULL;
        size_t line_bufsz = 0;
+       char *line = NULL;
        struct lxc_proc_context_info *info = NULL;
 
        /* Read capabilities. */
@@ -217,7 +218,8 @@ static struct lxc_proc_context_info 
*lxc_proc_get_context_info(pid_t pid)
        fclose(proc_file);
 
        if (!found) {
-               SYSERROR("Could not read capability bounding set from %s.", 
proc_fn);
+               SYSERROR("Could not read capability bounding set from %s.",
+                        proc_fn);
                errno = ENOENT;
                goto on_error;
        }
@@ -244,7 +246,6 @@ static int lxc_attach_to_ns(pid_t pid, int which)
        int fd[LXC_NS_MAX];
        int i, j, saved_errno;
 
-
        if (access("/proc/self/ns", X_OK)) {
                ERROR("Does this kernel version support namespaces?");
                return -1;
@@ -268,7 +269,8 @@ static int lxc_attach_to_ns(pid_t pid, int which)
                                close(fd[j]);
 
                        errno = saved_errno;
-                       SYSERROR("Failed to open namespace: \"%s\".", 
ns_info[i].proc_name);
+                       SYSERROR("Failed to open namespace: \"%s\".",
+                                ns_info[i].proc_name);
                        return -1;
                }
        }
@@ -284,7 +286,8 @@ static int lxc_attach_to_ns(pid_t pid, int which)
                                close(fd[j]);
 
                        errno = saved_errno;
-                       SYSERROR("Failed to attach to namespace \"%s\".", 
ns_info[i].proc_name);
+                       SYSERROR("Failed to attach to namespace \"%s\".",
+                                ns_info[i].proc_name);
                        return -1;
                }
 
@@ -307,7 +310,7 @@ static int lxc_attach_remount_sys_proc(void)
        }
 
        if (detect_shared_rootfs()) {
-               if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
+               if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL)) {
                        SYSERROR("Failed to make / rslave.");
                        ERROR("Continuing...");
                }
@@ -347,9 +350,9 @@ static int lxc_attach_remount_sys_proc(void)
 
 static int lxc_attach_drop_privs(struct lxc_proc_context_info *ctx)
 {
-       int last_cap = lxc_caps_last_cap();
-       int cap;
+       int cap, last_cap;
 
+       last_cap = lxc_caps_last_cap();
        for (cap = 0; cap <= last_cap; cap++) {
                if (ctx->capability_mask & (1LL << cap))
                        continue;
@@ -363,11 +366,12 @@ static int lxc_attach_drop_privs(struct 
lxc_proc_context_info *ctx)
        return 0;
 }
 
-static int lxc_attach_set_environment(enum lxc_attach_env_policy_t policy, 
char** extra_env, char** extra_keep)
+static int lxc_attach_set_environment(enum lxc_attach_env_policy_t policy,
+                                     char **extra_env, char **extra_keep)
 {
        if (policy == LXC_ATTACH_CLEAR_ENV) {
-               char **extra_keep_store = NULL;
                int path_kept = 0;
+               char **extra_keep_store = NULL;
 
                if (extra_keep) {
                        size_t count, i;
@@ -403,6 +407,7 @@ static int lxc_attach_set_environment(enum 
lxc_attach_env_policy_t policy, char*
 
                if (clearenv()) {
                        char **p;
+
                        SYSERROR("Failed to clear environment.");
                        if (extra_keep_store) {
                                for (p = extra_keep_store; *p; p++)
@@ -414,6 +419,7 @@ static int lxc_attach_set_environment(enum 
lxc_attach_env_policy_t policy, char*
 
                if (extra_keep_store) {
                        size_t i;
+
                        for (i = 0; extra_keep[i]; i++) {
                                if (extra_keep_store[i]) {
                                        if (setenv(extra_keep[i], 
extra_keep_store[i], 1) < 0)
@@ -462,10 +468,9 @@ static int lxc_attach_set_environment(enum 
lxc_attach_env_policy_t policy, char*
 
 static char *lxc_attach_getpwshell(uid_t uid)
 {
+       int fd, ret;
        pid_t pid;
        int pipes[2];
-       int ret;
-       int fd;
        char *result = NULL;
 
        /* We need to fork off a process that runs the getent program, and we
@@ -483,21 +488,20 @@ static char *lxc_attach_getpwshell(uid_t uid)
        }
 
        if (pid) {
+               int status;
                FILE *pipe_f;
-               char *line = NULL;
-               size_t line_bufsz = 0;
                int found = 0;
-               int status;
+               size_t line_bufsz = 0;
+               char *line = NULL;
 
                close(pipes[1]);
 
                pipe_f = fdopen(pipes[0], "r");
                while (getline(&line, &line_bufsz, pipe_f) != -1) {
-                       char *token;
-                       char *saveptr = NULL;
-                       long value;
-                       char *endptr = NULL;
                        int i;
+                       long value;
+                       char *token;
+                       char *endptr = NULL, *saveptr = NULL;
 
                        /* If we already found something, just continue to read
                         * until the pipe doesn't deliver any more data, but
@@ -608,7 +612,7 @@ static char *lxc_attach_getpwshell(uid_t uid)
        }
 }
 
-static void lxc_attach_get_init_uidgid(uid_t* init_uid, gid_t* init_gid)
+static void lxc_attach_get_init_uidgid(uid_t *init_uid, gid_t *init_gid)
 {
        FILE *proc_file;
        char proc_fn[__PROC_STATUS_LEN];
@@ -632,11 +636,11 @@ static void lxc_attach_get_init_uidgid(uid_t* init_uid, 
gid_t* init_gid)
                 */
                ret = sscanf(line, "Uid: %ld", &value);
                if (ret != EOF && ret == 1) {
-                       uid = (uid_t) value;
+                       uid = (uid_t)value;
                } else {
                        ret = sscanf(line, "Gid: %ld", &value);
                        if (ret != EOF && ret == 1)
-                               gid = (gid_t) value;
+                               gid = (gid_t)value;
                }
                if (uid != (uid_t)-1 && gid != (gid_t)-1)
                        break;
@@ -658,42 +662,45 @@ static void lxc_attach_get_init_uidgid(uid_t* init_uid, 
gid_t* init_gid)
 
 struct attach_clone_payload {
        int ipc_socket;
-       lxc_attach_options_t* options;
-       struct lxc_proc_context_info* init_ctx;
+       lxc_attach_options_t *options;
+       struct lxc_proc_context_info *init_ctx;
        lxc_attach_exec_t exec_function;
-       void* exec_payload;
+       void *exec_payload;
 };
 
 static int attach_child_main(void* data);
 
 /* Help the optimizer along if it doesn't know that exit always exits. */
-#define rexit(c)  do { int __c = (c); _exit(__c); return __c; } while(0)
+#define rexit(c)                                                               
\
+       do {                                                                   \
+               int __c = (c);                                                 \
+               _exit(__c);                                                    \
+               return __c;                                                    \
+       } while (0)
 
 /* Define default options if no options are supplied by the user. */
 static lxc_attach_options_t attach_static_default_options = 
LXC_ATTACH_OPTIONS_DEFAULT;
 
-static bool fetch_seccomp(const char *name, const char *lxcpath,
-               struct lxc_proc_context_info *i, lxc_attach_options_t *options)
+static bool fetch_seccomp(struct lxc_container *c,
+                         lxc_attach_options_t *options)
 {
-       struct lxc_container *c;
        char *path;
 
-       if (!(options->namespaces & CLONE_NEWNS) || !(options->attach_flags & 
LXC_ATTACH_LSM))
+       if (!(options->namespaces & CLONE_NEWNS) ||
+           !(options->attach_flags & LXC_ATTACH_LSM)) {
+               free(c->lxc_conf->seccomp);
+               c->lxc_conf->seccomp = NULL;
                return true;
+       }
 
-       c = lxc_container_new(name, lxcpath);
-       if (!c)
-               return false;
-       i->container = c;
-
-       /* Initialize an empty lxc_conf */
-       if (!c->set_config_item(c, "lxc.seccomp", "")) {
+       /* Remove current setting. */
+       if (!c->set_config_item(c, "lxc.seccomp", ""))
                return false;
-       }
 
        /* Fetch the current profile path over the cmd interface. */
        path = c->get_running_config_item(c, "lxc.seccomp");
        if (!path) {
+               INFO("Failed to get running config item for lxc.seccomp");
                return true;
        }
 
@@ -710,30 +717,35 @@ static bool fetch_seccomp(const char *name, const char 
*lxcpath,
                return false;
        }
 
+       INFO("Retrieved seccomp policy.");
        return true;
 }
 
 static signed long get_personality(const char *name, const char *lxcpath)
 {
-       char *p = lxc_cmd_get_config_item(name, "lxc.arch", lxcpath);
+       char *p;
        signed long ret;
 
+       p = lxc_cmd_get_config_item(name, "lxc.arch", lxcpath);
        if (!p)
                return -1;
+
        ret = lxc_config_parse_arch(p);
        free(p);
+
        return ret;
 }
 
-int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t 
exec_function, void* exec_payload, lxc_attach_options_t* options, pid_t* 
attached_process)
+int lxc_attach(const char *name, const char *lxcpath,
+              lxc_attach_exec_t exec_function, void *exec_payload,
+              lxc_attach_options_t *options, pid_t *attached_process)
 {
        int ret, status;
-       pid_t init_pid, pid, attached_pid, expected;
-       struct lxc_proc_context_info *init_ctx;
-       char* cwd;
-       char* new_cwd;
        int ipc_sockets[2];
+       char *cwd, *new_cwd;
        signed long personality;
+       pid_t attached_pid, expected, init_pid, pid;
+       struct lxc_proc_context_info *init_ctx;
 
        if (!options)
                options = &attach_static_default_options;
@@ -746,20 +758,19 @@ int lxc_attach(const char* name, const char* lxcpath, 
lxc_attach_exec_t exec_fun
 
        init_ctx = lxc_proc_get_context_info(init_pid);
        if (!init_ctx) {
-               ERROR("Failed to get context of init process: %ld.",
-                     (long)init_pid);
+               ERROR("Failed to get context of init process: %ld", 
(long)init_pid);
                return -1;
        }
 
        personality = get_personality(name, lxcpath);
        if (init_ctx->personality < 0) {
-               ERROR("Failed to get personality of the container.");
+               ERROR("Failed to get personality of the container");
                lxc_proc_put_context_info(init_ctx);
                return -1;
        }
        init_ctx->personality = personality;
 
-       if (!fetch_seccomp(name, lxcpath, init_ctx, options))
+       if (!fetch_seccomp(init_ctx->container, options))
                WARN("Failed to get seccomp policy.");
 
        cwd = getcwd(NULL, 0);
@@ -831,7 +842,6 @@ int lxc_attach(const char* name, const char* lxcpath, 
lxc_attach_exec_t exec_fun
         *          setns() (otherwise, user namespaces will hate us).
         */
        pid = fork();
-
        if (pid < 0) {
                SYSERROR("Failed to create first subprocess.");
                free(cwd);
@@ -874,7 +884,8 @@ int lxc_attach(const char* name, const char* lxcpath, 
lxc_attach_exec_t exec_fun
                }
 
                /* Get pid of attached process from intermediate process. */
-               ret = lxc_read_nointr_expect(ipc_sockets[0], &attached_pid, 
sizeof(attached_pid), NULL);
+               ret = lxc_read_nointr_expect(ipc_sockets[0], &attached_pid,
+                                            sizeof(attached_pid), NULL);
                if (ret <= 0) {
                        if (ret != 0)
                                ERROR("Expected to receive pid: %s.", 
strerror(errno));
@@ -905,7 +916,8 @@ int lxc_attach(const char* name, const char* lxcpath, 
lxc_attach_exec_t exec_fun
 
                /* Wait for the attached process to finish initializing. */
                expected = 1;
-               ret = lxc_read_nointr_expect(ipc_sockets[0], &status, 
sizeof(status), &expected);
+               ret = lxc_read_nointr_expect(ipc_sockets[0], &status,
+                                            sizeof(status), &expected);
                if (ret <= 0) {
                        if (ret != 0)
                                ERROR("Expected to receive sequence number 1: 
%s.", strerror(errno));
@@ -924,7 +936,8 @@ int lxc_attach(const char* name, const char* lxcpath, 
lxc_attach_exec_t exec_fun
                 * up its LSM labels.
                 */
                expected = 3;
-               ret = lxc_read_nointr_expect(ipc_sockets[0], &status, 
sizeof(status), &expected);
+               ret = lxc_read_nointr_expect(ipc_sockets[0], &status,
+                                            sizeof(status), &expected);
                if (ret <= 0) {
                        ERROR("Expected to receive sequence number 3: %s.",
                              strerror(errno));
@@ -932,9 +945,12 @@ int lxc_attach(const char* name, const char* lxcpath, 
lxc_attach_exec_t exec_fun
                }
 
                /* Open LSM fd and send it to child. */
-               if ((options->namespaces & CLONE_NEWNS) && 
(options->attach_flags & LXC_ATTACH_LSM) && init_ctx->lsm_label) {
+               if ((options->namespaces & CLONE_NEWNS) &&
+                   (options->attach_flags & LXC_ATTACH_LSM) &&
+                   init_ctx->lsm_label) {
                        int on_exec, saved_errno;
                        int labelfd = -1;
+
                        on_exec = options->attach_flags & LXC_ATTACH_LSM_EXEC ? 
1 : 0;
                        /* Open fd for the LSM security module. */
                        labelfd = lsm_openat(procfd, attached_pid, on_exec);
@@ -975,7 +991,7 @@ int lxc_attach(const char* name, const char* lxcpath, 
lxc_attach_exec_t exec_fun
                shutdown(ipc_sockets[0], SHUT_RDWR);
                close(ipc_sockets[0]);
                if (to_cleanup_pid)
-                       (void) wait_for_pid(to_cleanup_pid);
+                       (void)wait_for_pid(to_cleanup_pid);
                lxc_proc_put_context_info(init_ctx);
                return -1;
        }
@@ -988,7 +1004,8 @@ int lxc_attach(const char* name, const char* lxcpath, 
lxc_attach_exec_t exec_fun
        /* Wait for the parent to have setup cgroups. */
        expected = 0;
        status = -1;
-       ret = lxc_read_nointr_expect(ipc_sockets[1], &status, sizeof(status), 
&expected);
+       ret = lxc_read_nointr_expect(ipc_sockets[1], &status, sizeof(status),
+                                    &expected);
        if (ret <= 0) {
                ERROR("Expected to receive sequence number 0: %s.", 
strerror(errno));
                shutdown(ipc_sockets[1], SHUT_RDWR);
@@ -1062,21 +1079,17 @@ int lxc_attach(const char* name, const char* lxcpath, 
lxc_attach_exec_t exec_fun
 
 static int attach_child_main(void* data)
 {
-       struct attach_clone_payload* payload = (struct 
attach_clone_payload*)data;
-       int ipc_socket = payload->ipc_socket;
-       lxc_attach_options_t* options = payload->options;
-       struct lxc_proc_context_info* init_ctx = payload->init_ctx;
+       int expected, fd, lsm_labelfd, ret, status;
+       long flags;
 #if HAVE_SYS_PERSONALITY_H
        long new_personality;
 #endif
-       int ret;
-       int status;
-       int expected;
-       long flags;
-       int fd;
-       int lsm_labelfd;
        uid_t new_uid;
        gid_t new_gid;
+       struct attach_clone_payload* payload = (struct 
attach_clone_payload*)data;
+       int ipc_socket = payload->ipc_socket;
+       lxc_attach_options_t* options = payload->options;
+       struct lxc_proc_context_info* init_ctx = payload->init_ctx;
 
        /* Wait for the initial thread to signal us that it's ready for us to
         * start initializing.
@@ -1095,7 +1108,8 @@ static int attach_child_main(void* data)
         * parent process, otherwise /proc may not properly reflect the new pid
         * namespace.
         */
-       if (!(options->namespaces & CLONE_NEWNS) && (options->attach_flags & 
LXC_ATTACH_REMOUNT_PROC_SYS)) {
+       if (!(options->namespaces & CLONE_NEWNS) &&
+           (options->attach_flags & LXC_ATTACH_REMOUNT_PROC_SYS)) {
                ret = lxc_attach_remount_sys_proc();
                if (ret < 0) {
                        shutdown(ipc_socket, SHUT_RDWR);
@@ -1132,7 +1146,9 @@ static int attach_child_main(void* data)
        /* Always set the environment (specify (LXC_ATTACH_KEEP_ENV, NULL, NULL)
         * if you want this to be a no-op).
         */
-       ret = lxc_attach_set_environment(options->env_policy, 
options->extra_env_vars, options->extra_keep_env);
+       ret = lxc_attach_set_environment(options->env_policy,
+                                        options->extra_env_vars,
+                                        options->extra_keep_env);
        if (ret < 0) {
                ERROR("Could not set initial environment for attached 
process.");
                shutdown(ipc_socket, SHUT_RDWR);
@@ -1176,7 +1192,8 @@ static int attach_child_main(void* data)
                        rexit(-1);
                }
        }
-       if ((new_uid != 0 || options->namespaces & CLONE_NEWUSER) && 
setuid(new_uid)) {
+       if ((new_uid != 0 || options->namespaces & CLONE_NEWUSER) &&
+           setuid(new_uid)) {
                SYSERROR("Switching to container uid.");
                shutdown(ipc_socket, SHUT_RDWR);
                rexit(-1);
@@ -1213,7 +1230,8 @@ static int attach_child_main(void* data)
                rexit(-1);
        }
 
-       if ((options->namespaces & CLONE_NEWNS) && (options->attach_flags & 
LXC_ATTACH_LSM) && init_ctx->lsm_label) {
+       if ((options->namespaces & CLONE_NEWNS) &&
+           (options->attach_flags & LXC_ATTACH_LSM) && init_ctx->lsm_label) {
                int on_exec;
                /* Receive fd for LSM security module. */
                ret = lxc_abstract_unix_recv_fds(ipc_socket, &lsm_labelfd, 1, 
NULL, 0);
diff --git a/src/lxc/attach.h b/src/lxc/attach.h
index 39fcab783..fb6bc5a07 100644
--- a/src/lxc/attach.h
+++ b/src/lxc/attach.h
@@ -24,8 +24,8 @@
 #ifndef __LXC_ATTACH_H
 #define __LXC_ATTACH_H
 
-#include <sys/types.h>
 #include <lxc/attach_options.h>
+#include <sys/types.h>
 
 struct lxc_conf;
 
@@ -36,6 +36,8 @@ struct lxc_proc_context_info {
        unsigned long long capability_mask;
 };
 
-extern int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t 
exec_function, void* exec_payload, lxc_attach_options_t* options, pid_t* 
attached_process);
+extern int lxc_attach(const char *name, const char *lxcpath,
+                     lxc_attach_exec_t exec_function, void *exec_payload,
+                     lxc_attach_options_t *options, pid_t *attached_process);
 
-#endif
+#endif /* __LXC_ATTACH_H */
_______________________________________________
lxc-devel mailing list
[email protected]
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to