[lxc-devel] [lxc/master] add a pre-start-host hook

hallyn on Github lxc-bot at linuxcontainers.org
Wed Sep 20 23:16:41 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 1052 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170920/0f7e1491/attachment.bin>
-------------- next part --------------
From ae188acca4190c8c9fe5c6ada12fba27f3c74e89 Mon Sep 17 00:00:00 2001
From: Serge Hallyn <shallyn at cisco.com>
Date: Wed, 20 Sep 2017 21:22:46 +0000
Subject: [PATCH] add a pre-start-host hook

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.pre-start-host = /bin/lxc-prestart-netns

where /bin/lxc-prestart-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 at cisco.com>
---
 src/lxc/conf.c    |  5 ++++-
 src/lxc/conf.h    |  1 +
 src/lxc/confile.c |  4 ++++
 src/lxc/start.c   | 15 +++++++++++++--
 src/lxc/sync.h    |  2 +-
 5 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index b6dfa915c..a043b05a8 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -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",
+				      "pre-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, "pre-start-host") == 0)
+		which = LXCHOOK_PRESTART_HOST;
 	else if (strcmp(hook, "pre-mount") == 0)
 		which = LXCHOOK_PREMOUNT;
 	else if (strcmp(hook, "mount") == 0)
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 946ae4a23..292d5138a 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -228,6 +228,7 @@ enum lxchooks {
 	LXCHOOK_POSTSTOP,
 	LXCHOOK_CLONE,
 	LXCHOOK_DESTROY,
+	LXCHOOK_PRESTART_HOST,
 	NUM_LXC_HOOKS
 };
 
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index ed83d5dc8..bdc7f9494 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -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.pre-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, "pre-start-host") == 0)
+		return add_hook(lxc_conf, LXCHOOK_PRESTART_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, "pre-start-host\n");
 		strprint(retv, inlen, "start\n");
 		strprint(retv, inlen, "stop\n");
 	} else if (!strcmp(key, "lxc.cap")) {
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 3baed693a..7ddb6970f 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -1151,6 +1151,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;
@@ -1341,13 +1342,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 pre-start hooks */
+	if (run_lxc_hooks(name, "pre-start-host", handler->conf, handler->lxcpath, NULL)) {
+		ERROR("Failed to run lxc.hook.pre-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) {
diff --git a/src/lxc/sync.h b/src/lxc/sync.h
index 744db613e..5c0fb3431 100644
--- a/src/lxc/sync.h
+++ b/src/lxc/sync.h
@@ -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 */


More information about the lxc-devel mailing list