Commit a7242d9a by S.Çağlar Onur Committed by Stéphane Graber

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 avatarS.Çağlar Onur <caglar@10ur.org> Acked-by: 's avatarSerge E. Hallyn <serge.hallyn@ubuntu.com> Acked-by: 's avatarStéphane Graber <stgraber@ubuntu.com>
parent 7da8ab18
...@@ -3014,6 +3014,10 @@ void lxc_delete_network(struct lxc_handler *handler) ...@@ -3014,6 +3014,10 @@ void lxc_delete_network(struct lxc_handler *handler)
static int unpriv_assign_nic(struct lxc_netdev *netdev, pid_t pid) static int unpriv_assign_nic(struct lxc_netdev *netdev, pid_t pid)
{ {
pid_t child; 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) { if (netdev->type != LXC_NET_VETH) {
ERROR("nic type %d not support for unprivileged use", 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) ...@@ -3021,23 +3025,66 @@ static int unpriv_assign_nic(struct lxc_netdev *netdev, pid_t pid)
return -1; return -1;
} }
if(pipe(pipefd) < 0) {
SYSERROR("pipe failed");
return -1;
}
if ((child = fork()) < 0) { if ((child = fork()) < 0) {
SYSERROR("fork"); 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; return -1;
} }
if (child > 0) /* close the read-end of the pipe */
return wait_for_pid(child); 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]; return 0;
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);
} }
int lxc_assign_network(struct lxc_list *network, pid_t pid) int lxc_assign_network(struct lxc_list *network, pid_t pid)
......
...@@ -599,5 +599,7 @@ int main(int argc, char *argv[]) ...@@ -599,5 +599,7 @@ int main(int argc, char *argv[])
exit(1); exit(1);
} }
// write the name of the interface pair to the stdout - like eth0:veth9MT2L4
fprintf(stdout, "%s:%s\n", vethname, nicname);
exit(0); exit(0);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment