[lxc-devel] [PATCH] fill missing netdev fields for unprivileged containers
S.Çağlar Onur
caglar at 10ur.org
Sun Feb 16 21:20:48 UTC 2014
lxc-user-nic now returns the names of the interfaces and
unpriv_assign_nic function parses that information to fill
missing netdev->veth_attr.pair and netdev->name.
With this patch get_running_config_item started to provide
correct information;
>>> import lxc; c = lxc.Container("rubik"); c.get_running_config_item("lxc.network.0.name"); c.get_running_config_item("lxc.network.0.veth.pair");
'eth0'
'veth9MT2L4'
>>>
and lxc-info started to show network stats;
lxc-info -n rubik
Name: rubik
State: RUNNING
PID: 23061
IP: 10.0.3.233
CPU use: 3.86 seconds
BlkIO use: 88.00 KiB
Memory use: 6.53 MiB
KMem use: 0 bytes
Link: veth9MT2L4
TX bytes: 3.45 KiB
RX bytes: 8.83 KiB
Total bytes: 12.29 KiB
Signed-off-by: S.Çağlar Onur <caglar at 10ur.org>
---
src/lxc/conf.c | 67 ++++++++++++++++++++++++++++++++++++++++++--------
src/lxc/lxc_user_nic.c | 2 ++
2 files changed, 59 insertions(+), 10 deletions(-)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index e5df68b..10f46ae 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -3014,6 +3014,10 @@ void lxc_delete_network(struct lxc_handler *handler)
static int unpriv_assign_nic(struct lxc_netdev *netdev, pid_t pid)
{
pid_t child;
+ int bytes, pipefd[2];
+ char *token, *saveptr = NULL;
+ /* lxc-user-nic returns "interface_name:interface_name" format */
+ char buffer[IFNAMSIZ*2 + 1];
if (netdev->type != LXC_NET_VETH) {
ERROR("nic type %d not support for unprivileged use",
@@ -3021,23 +3025,66 @@ static int unpriv_assign_nic(struct lxc_netdev *netdev, pid_t pid)
return -1;
}
+ if(pipe(pipefd) < 0) {
+ SYSERROR("pipe failed");
+ return -1;
+ }
+
if ((child = fork()) < 0) {
SYSERROR("fork");
+ close(pipefd[0]);
+ close(pipefd[1]);
+ return -1;
+ }
+
+ if (child == 0) { // child
+ /* close the read-end of the pipe */
+ close(pipefd[0]);
+ /* redirect the stdout to write-end of the pipe */
+ dup2(pipefd[1], STDOUT_FILENO);
+ /* close the write-end of the pipe */
+ close(pipefd[0]);
+
+ // Call lxc-user-nic pid type bridge
+ char pidstr[20];
+ char *args[] = {LXC_USERNIC_PATH, pidstr, "veth", netdev->link, netdev->name, NULL };
+ snprintf(pidstr, 19, "%lu", (unsigned long) pid);
+ pidstr[19] = '\0';
+ execvp(args[0], args);
+ SYSERROR("execvp lxc-user-nic");
+ exit(1);
+ }
+
+ /* close the write-end of the pipe */
+ close(pipefd[1]);
+
+ bytes = read(pipefd[0], &buffer, IFNAMSIZ*2 + 1);
+ if (bytes < 0) {
+ SYSERROR("read failed");
+ }
+ buffer[bytes - 1] = '\0';
+
+ if (wait_for_pid(child) != 0) {
+ close(pipefd[0]);
return -1;
}
- if (child > 0)
- return wait_for_pid(child);
+ /* close the read-end of the pipe */
+ close(pipefd[0]);
+
+ /* fill netdev->name field */
+ token = strtok_r(buffer, ":", &saveptr);
+ if (!token)
+ return -1;
+ netdev->name = strdup(token);
- // Call lxc-user-nic pid type bridge
+ /* fill netdev->veth_attr.pair field */
+ token = strtok_r(NULL, ":", &saveptr);
+ if (!token)
+ return -1;
+ netdev->priv.veth_attr.pair = strdup(token);
- char pidstr[20];
- char *args[] = {LXC_USERNIC_PATH, pidstr, "veth", netdev->link, netdev->name, NULL };
- snprintf(pidstr, 19, "%lu", (unsigned long) pid);
- pidstr[19] = '\0';
- execvp(args[0], args);
- SYSERROR("execvp lxc-user-nic");
- exit(1);
+ return 0;
}
int lxc_assign_network(struct lxc_list *network, pid_t pid)
diff --git a/src/lxc/lxc_user_nic.c b/src/lxc/lxc_user_nic.c
index a2f0c96..ce79177 100644
--- a/src/lxc/lxc_user_nic.c
+++ b/src/lxc/lxc_user_nic.c
@@ -599,5 +599,7 @@ int main(int argc, char *argv[])
exit(1);
}
+ // write the name of the interface pair to the stdout - like eth0:veth9MT2L4
+ fprintf(stdout, "%s:%s\n", vethname, nicname);
exit(0);
}
--
1.8.3.2
More information about the lxc-devel
mailing list