[Devel] [RFC rh7] net: venet -- Cleanup ip address on ve exit

Andrey Vagin avagin at odin.com
Mon May 25 01:37:24 PDT 2015


On Wed, May 20, 2015 at 08:21:59PM +0300, Cyrill Gorcunov wrote:
> 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.
>

Acked-by: Andrey Vagin <avagin at odin.com>

> Signed-off-by: Cyrill Gorcunov <gorcunov at odin.com>
> CC: Vladimir Davydov <vdavydov at odin.com>
> CC: Konstantin Khorenko <khorenko at odin.com>
> CC: Pavel Emelyanov <xemul at odin.com>
> CC: Andrey Vagin <avagin at odin.com>
> ---
> 
> If there some better idea, please share.
> 
>  drivers/net/venetdev.c |   71 ++++++++++++++++++++++---------------------------
>  1 file changed, 32 insertions(+), 39 deletions(-)
> 
> Index: linux-pcs7.git/drivers/net/venetdev.c
> ===================================================================
> --- linux-pcs7.git.orig/drivers/net/venetdev.c
> +++ linux-pcs7.git/drivers/net/venetdev.c
> @@ -881,9 +881,13 @@ static int do_ve_ip_map(struct ve_struct
>  	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