[lxc-devel] [PATCH] fill missing netdev fields for unprivileged containers

Stéphane Graber stgraber at ubuntu.com
Sun Feb 16 21:59:05 UTC 2014


On Sun, Feb 16, 2014 at 04:20:48PM -0500, S.Çağlar Onur wrote:
> 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.

Cool, I'll test it in a bit, I wonder if this also means that
lxc.network.hwaddr now actually works for unprivileged containers (which
would be a great improvement as my DHCP server ran at of IPs a few times
by now ;)).


Thanks for that work!

> 
> 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
> 
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel

-- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20140216/874d1c95/attachment.pgp>


More information about the lxc-devel mailing list