From: S.Çağlar Onur Date: Sun, 16 Feb 2014 21:20:48 +0000 (-0500) Subject: fill missing netdev fields for unprivileged containers X-Git-Tag: lxc-1.0.0.rc3~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a7242d9a58ac7efef9fb97aaaadcdf760bd13230;p=thirdparty%2Flxc.git fill missing netdev fields for unprivileged containers 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 Acked-by: Serge E. Hallyn Acked-by: Stéphane Graber --- diff --git a/src/lxc/conf.c b/src/lxc/conf.c index e5df68bff..10f46aef1 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 a2f0c96b9..ce7917725 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); }