[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