From ef3771d566dacb8ee9fe71b744d56f08674fe3db Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Fri, 19 Oct 2012 17:35:46 +0400 Subject: [PATCH] net: Introduce netdev index to name resolver It will be required to support socket bound to devices. When restoring w/o net namespaces -- collect existing devices. When restoring with them -- collect what is received from image. Signed-off-by: Pavel Emelyanov --- cr-restore.c | 3 +++ include/net.h | 3 +++ net.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) diff --git a/cr-restore.c b/cr-restore.c index c2d1cbd98..9c8a7297c 100644 --- a/cr-restore.c +++ b/cr-restore.c @@ -764,6 +764,9 @@ static int restore_task_with_children(void *_arg) if (collect_mount_info()) exit(-1); + if (collect_net_devs(ca->clone_flags)) + exit(-1); + if (prepare_namespace(current->pid.virt, ca->clone_flags)) exit(-1); diff --git a/include/net.h b/include/net.h index fb55e0777..edfde269a 100644 --- a/include/net.h +++ b/include/net.h @@ -19,4 +19,7 @@ struct veth_pair { extern int network_lock(void); extern void network_unlock(void); + +char *resolve_dev_name(int index); +int collect_net_devs(unsigned long flags); #endif diff --git a/net.c b/net.c index 3d8ef852c..4770054c8 100644 --- a/net.c +++ b/net.c @@ -6,6 +6,8 @@ #include #include #include +#include + #include "syscall-types.h" #include "namespaces.h" #include "net.h" @@ -18,6 +20,8 @@ static int ns_fd = -1; +static int collect_one_netdev(int idx, char *name); + void show_netdevices(int fd, struct cr_options *opt) { pb_show_plain_pretty(fd, PB_NETDEV, "2:%d"); @@ -270,6 +274,9 @@ static int restore_links(int pid) break; ret = restore_link(nde, nlsk); + if (!ret) + ret = collect_one_netdev(nde->ifindex, nde->name); + net_device_entry__free_unpacked(nde, NULL); if (ret) break; @@ -401,3 +408,70 @@ void network_unlock(void) run_scripts("network-unlock"); } +struct net_dev { + int idx; + char name[IFNAMSIZ]; + struct net_dev *next; +}; + +static struct net_dev *net_devs; + +static int collect_one_netdev(int idx, char *name) +{ + struct net_dev *nd; + + nd = xmalloc(sizeof(*nd)); + if (!nd) + return -1; + + nd->idx = idx; + strncpy(nd->name, name, IFNAMSIZ); + nd->next = net_devs; + net_devs = nd; + + pr_debug("\tCollected %d:%s netdev\n", idx, name); + + return 0; +} + +static int collect_netdev(struct nlmsghdr *hdr, void *arg) +{ + struct ifinfomsg *ifi; + int len = hdr->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)); + struct rtattr *tb[IFLA_MAX + 1]; + + ifi = NLMSG_DATA(hdr); + if (len < 0) { + pr_err("No iflas for link %d\n", ifi->ifi_index); + return -1; + } + + parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); + if (!tb[IFLA_IFNAME]) { + pr_err("No name for device %d\n", ifi->ifi_index); + return -1; + } + + return collect_one_netdev(ifi->ifi_index, RTA_DATA(tb[IFLA_IFNAME])); +} + +int collect_net_devs(unsigned long flags) +{ + if (flags & CLONE_NEWNET) + /* restore_links() will collect them */ + return 0; + + pr_info("Collecting net devices\n"); + return do_dump_links(collect_netdev, NULL); +} + +char *resolve_dev_name(int index) +{ + struct net_dev *nd; + + for (nd = net_devs; nd; nd = nd->next) + if (nd->idx == index) + return nd->name; + + return NULL; +}