]> git.proxmox.com Git - mirror_lxc.git/commitdiff
add a start-host hook (v2)
authorSerge Hallyn <shallyn@cisco.com>
Wed, 20 Sep 2017 21:22:46 +0000 (21:22 +0000)
committerSerge Hallyn <shallyn@cisco.com>
Sat, 30 Sep 2017 21:55:02 +0000 (21:55 +0000)
This should satisfy several use cases.  The one I tested for was CNI.
I replaced the network configuration in a root owned container with:

lxc.net.0.type = empty
lxc.hook.start-host = /bin/lxc-start-netns

where /bin/lxc-start-netns contained:

=================================

echo "starting" > /tmp/debug
ip link add host1 type veth peer name peer1
ip link set host1 master lxcbr0
ip link set host1 up
ip link set peer1 netns "${LXC_PID}"
=================================

The nic 'peer1' was placed into the container as expected.

For this to work, we pass the container init's pid as LXC_PID in
an environment variable, since lxc-info cannot work at that point.

Signed-off-by: Serge Hallyn <shallyn@cisco.com>
doc/lxc.container.conf.sgml.in
src/lxc/conf.c
src/lxc/conf.h
src/lxc/confile.c
src/lxc/start.c
src/lxc/sync.h

index 316327985088e0c75726656428373cc9b4e7ec59..287bc8e517cf5c92a71962ad962e4f71b4202ab9 100644 (file)
@@ -1519,6 +1519,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
           </listitem>
         </varlistentry>
       </variablelist>
+      <variablelist>
+        <varlistentry>
+          <term>
+            <option>lxc.hook.start-host</option>
+          </term>
+          <listitem>
+            <para>
+              A hook to be run in the host's namespace after the
+              container has been setup, and immediately before starting
+             the container init.
+            </para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
       <variablelist>
         <varlistentry>
           <term>
index b6dfa915cf93caa29971423ed74c39253659ae8f..0b5a9e2600cdd4234b48eca12c2b3309e7556c8d 100644 (file)
@@ -236,7 +236,8 @@ extern int memfd_create(const char *name, unsigned int flags);
 
 char *lxchook_names[NUM_LXC_HOOKS] = {"pre-start", "pre-mount", "mount",
                                      "autodev",   "start",     "stop",
-                                     "post-stop", "clone",     "destroy"};
+                                     "post-stop", "clone",     "destroy",
+                                     "start-host"};
 
 struct mount_opt {
        char *name;
@@ -3285,6 +3286,8 @@ int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf,
 
        if (strcmp(hook, "pre-start") == 0)
                which = LXCHOOK_PRESTART;
+       else if (strcmp(hook, "start-host") == 0)
+               which = LXCHOOK_START_HOST;
        else if (strcmp(hook, "pre-mount") == 0)
                which = LXCHOOK_PREMOUNT;
        else if (strcmp(hook, "mount") == 0)
index 946ae4a2376aeca192479f50ebbc9efec6872e7a..1bc02dc4f3206c82dd289d0da8c3469e77d1f140 100644 (file)
@@ -228,6 +228,7 @@ enum lxchooks {
        LXCHOOK_POSTSTOP,
        LXCHOOK_CLONE,
        LXCHOOK_DESTROY,
+       LXCHOOK_START_HOST,
        NUM_LXC_HOOKS
 };
 
index ed83d5dc871055948b90c7527b071c8d66ae3ea8..1beb9c7b4b1a851e7ff8d68084f6c28f6830842e 100644 (file)
@@ -155,6 +155,7 @@ static struct lxc_config_t config[] = {
        { "lxc.hook.destroy",              false,                  set_config_hooks,                       get_config_hooks,                       clr_config_hooks,                     },
        { "lxc.hook.mount",                false,                  set_config_hooks,                       get_config_hooks,                       clr_config_hooks,                     },
        { "lxc.hook.post-stop",            false,                  set_config_hooks,                       get_config_hooks,                       clr_config_hooks,                     },
+       { "lxc.hook.start-host",           false,                  set_config_hooks,                       get_config_hooks,                       clr_config_hooks,                     },
        { "lxc.hook.pre-start",            false,                  set_config_hooks,                       get_config_hooks,                       clr_config_hooks,                     },
        { "lxc.hook.pre-mount",            false,                  set_config_hooks,                       get_config_hooks,                       clr_config_hooks,                     },
        { "lxc.hook.start",                false,                  set_config_hooks,                       get_config_hooks,                       clr_config_hooks,                     },
@@ -980,6 +981,8 @@ static int set_config_hooks(const char *key, const char *value,
 
        if (strcmp(key + 9, "pre-start") == 0)
                return add_hook(lxc_conf, LXCHOOK_PRESTART, copy);
+       else if (strcmp(key + 9, "start-host") == 0)
+               return add_hook(lxc_conf, LXCHOOK_START_HOST, copy);
        else if (strcmp(key + 9, "pre-mount") == 0)
                return add_hook(lxc_conf, LXCHOOK_PREMOUNT, copy);
        else if (strcmp(key + 9, "autodev") == 0)
@@ -4445,6 +4448,7 @@ int lxc_list_subkeys(struct lxc_conf *conf, const char *key, char *retv,
                strprint(retv, inlen, "post-stop\n");
                strprint(retv, inlen, "pre-mount\n");
                strprint(retv, inlen, "pre-start\n");
+               strprint(retv, inlen, "start-host\n");
                strprint(retv, inlen, "start\n");
                strprint(retv, inlen, "stop\n");
        } else if (!strcmp(key, "lxc.cap")) {
index b838e579d19135edd9cfd6ea54d6a7fdcb4dae1c..d8460403ec938c77b35342a484e346a62e511cc0 100644 (file)
@@ -1165,6 +1165,7 @@ static int lxc_spawn(struct lxc_handler *handler)
 {
        int i, flags, ret;
        const char *name = handler->name;
+       char pidstr[20];
        bool wants_to_map_ids;
        int saved_ns_fd[LXC_NS_MAX];
        struct lxc_list *id_map;
@@ -1355,13 +1356,23 @@ static int lxc_spawn(struct lxc_handler *handler)
        cgroup_disconnect();
        cgroups_connected = false;
 
+       snprintf(pidstr, 20, "%d", handler->pid);
+       if (setenv("LXC_PID", pidstr, 1))
+               SYSERROR("Failed to set environment variable: LXC_PID=%s.", pidstr);
+
+       /* Run any host-side start hooks */
+       if (run_lxc_hooks(name, "start-host", handler->conf, handler->lxcpath, NULL)) {
+               ERROR("Failed to run lxc.hook.start-host for container \"%s\".", name);
+               return -1;
+       }
+
        /* Tell the child to complete its initialization and wait for it to exec
         * or return an error. (The child will never return
-        * LXC_SYNC_POST_CGROUP+1. It will either close the sync pipe, causing
+        * LXC_SYNC_READY_START+1. It will either close the sync pipe, causing
         * lxc_sync_barrier_child to return success, or return a different
         * value, causing us to error out).
         */
-       if (lxc_sync_barrier_child(handler, LXC_SYNC_POST_CGROUP))
+       if (lxc_sync_barrier_child(handler, LXC_SYNC_READY_START))
                return -1;
 
        if (lxc_network_recv_name_and_ifindex_from_child(handler) < 0) {
index 744db613e4d813ba2a766cd23dbd196d35c43da8..5c0fb34310eb2cf8de2613704885faaefff371b4 100644 (file)
@@ -32,7 +32,7 @@ enum {
        LXC_SYNC_CGROUP,
        LXC_SYNC_CGROUP_UNSHARE,
        LXC_SYNC_CGROUP_LIMITS,
-       LXC_SYNC_POST_CGROUP,
+       LXC_SYNC_READY_START,
        LXC_SYNC_RESTART,
        LXC_SYNC_POST_RESTART,
        LXC_SYNC_ERROR = -1 /* Used to report errors from another process */