[lxc-devel] [lxc/master] netns: improve netnsid allocation

brauner on Github lxc-bot at linuxcontainers.org
Sat Aug 11 00:24:51 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 364 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180811/b6a1b12e/attachment.bin>
-------------- next part --------------
From 4e3ed0d1969a31b977e8b88a44e30ce91ef5c1e4 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Sat, 11 Aug 2018 02:21:14 +0200
Subject: [PATCH 1/3] macro: add NLMSG_ERROR

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/macro.h | 4 ++++
 src/lxc/nl.c    | 3 ---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/lxc/macro.h b/src/lxc/macro.h
index 83c40cef0..3ef0ab4c2 100644
--- a/src/lxc/macro.h
+++ b/src/lxc/macro.h
@@ -187,4 +187,8 @@ extern int __build_bug_on_failed;
 #define RTM_NEWNSID 88
 #endif
 
+#ifndef NLMSG_ERROR
+#define NLMSG_ERROR 0x2
+#endif
+
 #endif /* __LXC_MACRO_H */
diff --git a/src/lxc/nl.c b/src/lxc/nl.c
index dfe71110f..c83c587e8 100644
--- a/src/lxc/nl.c
+++ b/src/lxc/nl.c
@@ -237,9 +237,6 @@ extern int netlink_send(struct nl_handler *handler, struct nlmsg *nlmsg)
 	return ret;
 }
 
-#ifndef NLMSG_ERROR
-#define NLMSG_ERROR                0x2
-#endif
 extern int netlink_transaction(struct nl_handler *handler,
 			       struct nlmsg *request, struct nlmsg *answer)
 {

From 0ce60f0d5f3d53d554572c144ca0c5c2fec742f9 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Sat, 11 Aug 2018 02:21:34 +0200
Subject: [PATCH 2/3] netns: improve netnsid allocation

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/network.c | 126 ++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 104 insertions(+), 22 deletions(-)

diff --git a/src/lxc/network.c b/src/lxc/network.c
index d0824690f..53bc58111 100644
--- a/src/lxc/network.c
+++ b/src/lxc/network.c
@@ -3192,16 +3192,102 @@ enum {
 	__LXC_NETNSA_MAX,
 };
 
+static int nl_send(struct nl_handler *handler, struct nlmsghdr *nlmsghdr)
+{
+	struct sockaddr_nl nladdr;
+	struct iovec iov = {
+		.iov_base = nlmsghdr,
+		.iov_len = nlmsghdr->nlmsg_len,
+	};
+	struct msghdr msg = {
+		.msg_name = &nladdr,
+		.msg_namelen = sizeof(nladdr),
+		.msg_iov = &iov,
+		.msg_iovlen = 1,
+	};
+	int ret;
+
+	memset(&nladdr, 0, sizeof(nladdr));
+	nladdr.nl_family = AF_NETLINK;
+	nladdr.nl_pid = 0;
+	nladdr.nl_groups = 0;
+
+	ret = sendmsg(handler->fd, &msg, MSG_NOSIGNAL);
+	if (ret < 0)
+		return -errno;
+
+	return ret;
+}
+
+static int nl_recv(struct nl_handler *handler, struct nlmsghdr *nlmsghdr)
+{
+	int ret;
+	struct sockaddr_nl nladdr;
+	struct iovec iov = {
+	    .iov_base = nlmsghdr,
+	    .iov_len = nlmsghdr->nlmsg_len,
+	};
+
+	struct msghdr msg = {
+		.msg_name = &nladdr,
+		.msg_namelen = sizeof(nladdr),
+		.msg_iov = &iov,
+		.msg_iovlen = 1,
+	};
+
+	memset(&nladdr, 0, sizeof(nladdr));
+	nladdr.nl_family = AF_NETLINK;
+	nladdr.nl_pid = 0;
+	nladdr.nl_groups = 0;
+
+again:
+	ret = recvmsg(handler->fd, &msg, 0);
+	if (ret < 0) {
+		if (errno == EINTR)
+			goto again;
+
+		return -1;
+	}
+
+	if (!ret)
+		return 0;
+
+	if (msg.msg_flags & MSG_TRUNC && (ret == nlmsghdr->nlmsg_len))
+		return -EMSGSIZE;
+
+	return ret;
+}
+
+extern int nl_transaction(struct nl_handler *handler, struct nlmsghdr *request,
+			  struct nlmsghdr *answer)
+{
+	int ret;
+
+	ret = nl_send(handler, request);
+	if (ret < 0)
+		return ret;
+
+	ret = nl_recv(handler, answer);
+	if (ret < 0)
+		return ret;
+
+	if (answer->nlmsg_type == NLMSG_ERROR) {
+		struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(answer);
+		return err->error;
+	}
+
+	return 0;
+}
+
 int lxc_netns_set_nsid(int fd)
 {
 	ssize_t ret;
-	char l_buffer[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
-		      NLMSG_ALIGN(sizeof(struct rtgenmsg)) +
-		      NLMSG_ALIGN(1024)];
+	char buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
+		 NLMSG_ALIGN(sizeof(struct rtgenmsg)) +
+		 NLMSG_ALIGN(1024)];
 	struct nl_handler nlh;
-	struct nlmsghdr *l_hdr;
-	struct rtgenmsg *l_msg;
-	struct sockaddr_nl l_addr;
+	struct nlmsghdr *hdr;
+	struct rtgenmsg *msg;
 	__s32 ns_id = -1;
 	__u32 netns_fd = fd;
 
@@ -3209,25 +3295,21 @@ int lxc_netns_set_nsid(int fd)
 	if (ret < 0)
 		return ret;
 
-	memset(l_buffer, 0, sizeof(l_buffer));
-	l_hdr = (struct nlmsghdr *)l_buffer;
-	l_msg = (struct rtgenmsg *)NLMSG_DATA(l_hdr);
-
-	l_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*l_msg));
-	l_hdr->nlmsg_type = RTM_NEWNSID;
-	l_hdr->nlmsg_flags = NLM_F_REQUEST;
-	l_hdr->nlmsg_pid = 0;
-	l_hdr->nlmsg_seq = RTM_NEWNSID;
-	l_msg->rtgen_family = AF_UNSPEC;
+	memset(buf, 0, sizeof(buf));
+	hdr = (struct nlmsghdr *)buf;
+	msg = (struct rtgenmsg *)NLMSG_DATA(hdr);
 
-	addattr(l_hdr, 1024, __LXC_NETNSA_FD, &netns_fd, sizeof(netns_fd));
-	addattr(l_hdr, 1024, __LXC_NETNSA_NSID, &ns_id, sizeof(ns_id));
+	hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*msg));
+	hdr->nlmsg_type = RTM_NEWNSID;
+	hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+	hdr->nlmsg_pid = 0;
+	hdr->nlmsg_seq = RTM_NEWNSID;
+	msg->rtgen_family = AF_UNSPEC;
 
-	memset(&l_addr, 0, sizeof(l_addr));
-	l_addr.nl_family = AF_NETLINK;
+	addattr(hdr, 1024, __LXC_NETNSA_FD, &netns_fd, sizeof(netns_fd));
+	addattr(hdr, 1024, __LXC_NETNSA_NSID, &ns_id, sizeof(ns_id));
 
-	ret = sendto(nlh.fd, l_hdr, l_hdr->nlmsg_len, 0,
-		     (struct sockaddr *)&l_addr, sizeof(l_addr));
+	ret = nl_transaction(&nlh, hdr, hdr);
 	netlink_close(&nlh);
 	if (ret < 0)
 		return -1;

From ea69d8c01fdf2ff77cbe4a38bcbca150740fe7f1 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Sat, 11 Aug 2018 02:23:16 +0200
Subject: [PATCH 3/3] start: make netnsid allocation failures non-fatal

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/start.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/lxc/start.c b/src/lxc/start.c
index 2485472e2..51c33193a 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -1821,10 +1821,11 @@ static int lxc_spawn(struct lxc_handler *handler)
 
 		ret = lxc_netns_set_nsid(handler->nsfd[LXC_NS_NET]);
 		if (ret < 0) {
-			ERROR("Failed to allocate new network namespace id: %d", ret);
-			goto out_delete_net;
+			errno = -ret SYSERROR(
+			    "Failed to allocate new network namespace id");
+		} else {
+			TRACE("Allocated new network namespace id");
 		}
-		TRACE("Allocated new network namespace id");
 	}
 
 	/* Create the network configuration. */


More information about the lxc-devel mailing list