[lxc-devel] [PATCH] fill missing netdev fields for unprivileged containers
Serge Hallyn
serge.hallyn at ubuntu.com
Mon Feb 17 15:58:03 UTC 2014
Quoting S.Çağlar Onur (caglar at 10ur.org):
> 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>
Acked-by: Serge E. Hallyn <serge.hallyn at ubuntu.com>
> ---
> 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];
I'd prefer it be +2 and you stick a 0 at the end.
the +1 shoudl be for the ':' you put between the names. Then you need
another +1 for the \0.
>
> 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]);
You meant pipefd[1] here?
> +
> + // 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
>
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel
More information about the lxc-devel
mailing list