[Devel] [PATCH RHEL7 COMMIT] venet: Cleanup ip address on ve exit
Konstantin Khorenko
khorenko at virtuozzo.com
Thu May 28 06:38:28 PDT 2015
The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.7
------>
commit de376c7c241bb28faec8413bac9b3d991e51853c
Author: Cyrill Gorcunov <gorcunov at odin.com>
Date: Thu May 28 17:38:28 2015 +0400
venet: Cleanup ip address on ve exit
While been playing with c/r of a container with IP assigned I found that
VE exit (ve_drop_context) is happening earlier than venet::exit
routine which means the ve::ve_netns = nil when we enter into
ip releasing procedure.
| zap_pid_ns_processes
| ve_stop_ns
| ve_exit_ns
| ve_drop_context(ve);
| put_net(ve->ve_netns);
| ve->ve_netns = NULL;
Releasing ve context that early looks logical because ve::ve_netns
is a part of ve structure itself, in turn ip address and venet device
is rather a side feature provided by venet module.
So because we do not create nested venet devices and adding
some additional ioctl makes code only harder to read I propose
to use VE exit hook to cleanup ip address.
With the patch applied I can checkpoint/restore container
with venet configured.
Signed-off-by: Cyrill Gorcunov <gorcunov at odin.com>
Acked-by: Andrey Vagin <avagin at odin.com>
CC: Vladimir Davydov <vdavydov at odin.com>
CC: Konstantin Khorenko <khorenko at odin.com>
CC: Pavel Emelyanov <xemul at odin.com>
---
drivers/net/venetdev.c | 71 +++++++++++++++++++++++---------------------------
1 file changed, 32 insertions(+), 39 deletions(-)
diff --git a/drivers/net/venetdev.c b/drivers/net/venetdev.c
index bb7f0be..6b7d8fc7 100644
--- a/drivers/net/venetdev.c
+++ b/drivers/net/venetdev.c
@@ -881,9 +881,13 @@ static int do_ve_ip_map(struct ve_struct *ve, int op, struct ve_addr_struct *add
switch (op)
{
case VE_IP_ADD:
- err = -ESRCH;
- if (ve->is_running)
- err = veip_entry_add(ve, addr);
+ /*
+ * FIXME We should check if VE
+ * is either running or in restore
+ * state instead of allowing adding
+ * address arbitrary.
+ */
+ err = veip_entry_add(ve, addr);
break;
case VE_IP_DEL:
@@ -1113,51 +1117,39 @@ err:
return err;
}
-static __net_exit void venet_exit_net(struct list_head *net_exit_list)
+static struct pernet_operations venet_net_ops = {
+ .init = venet_init_net,
+};
+
+/*
+ * VE context dropping is happening earlier than
+ * pernet_operations::exit method so we can't
+ * rely on it and do the cleanup earlier.
+ */
+static void venet_stop_notifier(void *data)
{
- struct net *net;
- struct ve_struct *env;
- struct net_device *dev;
- LIST_HEAD(netdev_kill_list);
+ struct ve_struct *env = data;
- list_for_each_entry(net, net_exit_list, exit_list) {
- env = net->owner_ve;
- if (env->ve_netns != net)
- continue;
+ if (env->ve_netns) {
+ struct net_device *dev = env->_venet_dev;
venet_ext_clean(env);
veip_stop(env);
- dev = env->_venet_dev;
- if (dev == NULL)
- continue;
-
- rtnl_lock();
- unregister_netdevice_queue(dev, &netdev_kill_list);
- rtnl_unlock();
- }
-
- rtnl_lock();
- unregister_netdevice_many(&netdev_kill_list);
- rtnl_unlock();
-
- list_for_each_entry(net, net_exit_list, exit_list) {
- env = net->owner_ve;
- if (env->ve_netns != net)
- continue;
-
- dev = env->_venet_dev;
- if (dev == NULL)
- continue;
-
- env->_venet_dev = NULL;
- free_netdev(dev);
+ if (dev) {
+ env->_venet_dev = NULL;
+ rtnl_lock();
+ unregister_netdevice(dev);
+ rtnl_unlock();
+ free_netdev(dev);
+ }
}
}
-static struct pernet_operations venet_net_ops = {
- .init = venet_init_net,
- .exit_batch = venet_exit_net,
+static struct ve_hook venet_stop_hook = {
+ .fini = venet_stop_notifier,
+ .priority = HOOK_PRIO_FINISHING,
+ .owner = THIS_MODULE,
};
static int venet_changelink(struct net_device *dev, struct nlattr *tb[],
@@ -1241,6 +1233,7 @@ __init int venet_init(void)
vzioctl_register(&venetcalls);
vzmon_register_veaddr_print_cb(veaddr_seq_print);
+ ve_hook_register(VE_SS_CHAIN, &venet_stop_hook);
return rtnl_link_register(&venet_link_ops);
More information about the Devel
mailing list