Re: [PATCH 3/3] IPVS: init and cleanup restructuring.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Apr 19, 2011 at 05:25:05PM +0200, Hans Schillstrom wrote:
> This patch tries to restore the initial init and cleanup
> sequences that was before name space patch.
> 
> The number of calls to register_pernet_device have been
> reduced to one for the ip_vs.ko
> Schedulers still have their own calls.
> 
> This patch adds a function __ip_vs_service_cleanup()
> and a throttle or actually on/off switch for
> the netfilter hooks.
> 
> The nf hooks will be enabled when the first service is loaded
> and disabled when the last service is removed or when a
> name space exit starts.
> 
> Signed-off-by: Hans Schillstrom <hans@xxxxxxxxxxxxxxx>
> ---
>  include/net/ip_vs.h              |   17 +++++++
>  net/netfilter/ipvs/ip_vs_app.c   |   15 +-----
>  net/netfilter/ipvs/ip_vs_conn.c  |   20 ++++----
>  net/netfilter/ipvs/ip_vs_core.c  |   86 ++++++++++++++++++++++++++++++++------
>  net/netfilter/ipvs/ip_vs_ctl.c   |   66 ++++++++++++++++++++++-------
>  net/netfilter/ipvs/ip_vs_est.c   |   14 +-----
>  net/netfilter/ipvs/ip_vs_proto.c |   11 +----
>  net/netfilter/ipvs/ip_vs_sync.c  |   13 +----
>  8 files changed, 161 insertions(+), 81 deletions(-)
> 
> diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
> index d516f00..558e490 100644
> --- a/include/net/ip_vs.h
> +++ b/include/net/ip_vs.h
> @@ -791,6 +791,7 @@ struct ip_vs_app {
>  /* IPVS in network namespace */
>  struct netns_ipvs {
>  	int			gen;		/* Generation */
> +	int			throttle;	/* Instead of nf unreg */

perhaps enable or active would be names that fits better with the
schemantics used.  Using a bool might also make things more obvious.

>  	/*
>  	 *	Hash table: for real service lookups
>  	 */
> @@ -1089,6 +1090,22 @@ ip_vs_control_add(struct ip_vs_conn *cp, struct ip_vs_conn *ctl_cp)
>  	atomic_inc(&ctl_cp->n_control);
>  }
> 
> +/*
> + * IPVS netns init & cleanup functions
> + */
> +extern int __ip_vs_estimator_init(struct net *net);
> +extern int __ip_vs_control_init(struct net *net);
> +extern int __ip_vs_protocol_init(struct net *net);
> +extern int __ip_vs_app_init(struct net *net);
> +extern int __ip_vs_conn_init(struct net *net);
> +extern int __ip_vs_sync_init(struct net *net);
> +extern void __ip_vs_conn_cleanup(struct net *net);
> +extern void __ip_vs_app_cleanup(struct net *net);
> +extern void __ip_vs_protocol_cleanup(struct net *net);
> +extern void __ip_vs_control_cleanup(struct net *net);
> +extern void __ip_vs_estimator_cleanup(struct net *net);
> +extern void __ip_vs_sync_cleanup(struct net *net);
> +extern void __ip_vs_service_cleanup(struct net *net);
> 
>  /*
>   *      IPVS application functions
> diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c
> index 7e8e769..51f3af7 100644
> --- a/net/netfilter/ipvs/ip_vs_app.c
> +++ b/net/netfilter/ipvs/ip_vs_app.c
> @@ -576,7 +576,7 @@ static const struct file_operations ip_vs_app_fops = {
>  };
>  #endif
> 
> -static int __net_init __ip_vs_app_init(struct net *net)
> +int __net_init __ip_vs_app_init(struct net *net)
>  {
>  	struct netns_ipvs *ipvs = net_ipvs(net);
> 
> @@ -585,26 +585,17 @@ static int __net_init __ip_vs_app_init(struct net *net)
>  	return 0;
>  }
> 
> -static void __net_exit __ip_vs_app_cleanup(struct net *net)
> +void __net_exit __ip_vs_app_cleanup(struct net *net)
>  {
>  	proc_net_remove(net, "ip_vs_app");
>  }
> 
> -static struct pernet_operations ip_vs_app_ops = {
> -	.init = __ip_vs_app_init,
> -	.exit = __ip_vs_app_cleanup,
> -};
> -
>  int __init ip_vs_app_init(void)
>  {
> -	int rv;
> -
> -	rv = register_pernet_device(&ip_vs_app_ops);
> -	return rv;
> +	return 0;
>  }
> 
> 
>  void ip_vs_app_cleanup(void)
>  {
> -	unregister_pernet_device(&ip_vs_app_ops);
>  }

Can we just remove ip_vs_app_init() and ip_vs_app_cleanup() as
they no longer do anything? Likewise with other init and cleanup
functions below.

> diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
> index 36cd5ea..f8d6702 100644
> --- a/net/netfilter/ipvs/ip_vs_conn.c
> +++ b/net/netfilter/ipvs/ip_vs_conn.c
> @@ -1251,30 +1251,30 @@ int __net_init __ip_vs_conn_init(struct net *net)
>  {
>  	struct netns_ipvs *ipvs = net_ipvs(net);
> 
> +	EnterFunction(2);
>  	atomic_set(&ipvs->conn_count, 0);
> 
>  	proc_net_fops_create(net, "ip_vs_conn", 0, &ip_vs_conn_fops);
>  	proc_net_fops_create(net, "ip_vs_conn_sync", 0, &ip_vs_conn_sync_fops);
> +	LeaveFunction(2);
>  	return 0;
>  }

Does adding these EnterFunction() and LeaveFunction() calls
restore some previous behaviour? If not, I think they should at the very
least be in a separate patch. Likewise for similar changes below.

> 
> -static void __net_exit __ip_vs_conn_cleanup(struct net *net)
> +void __net_exit __ip_vs_conn_cleanup(struct net *net)
>  {
> +	EnterFunction(2);
>  	/* flush all the connection entries first */
>  	ip_vs_conn_flush(net);
>  	proc_net_remove(net, "ip_vs_conn");
>  	proc_net_remove(net, "ip_vs_conn_sync");
> +	LeaveFunction(2);
>  }
> -static struct pernet_operations ipvs_conn_ops = {
> -	.init = __ip_vs_conn_init,
> -	.exit = __ip_vs_conn_cleanup,
> -};
> 
>  int __init ip_vs_conn_init(void)
>  {
>  	int idx;
> -	int retc;
> 
> +	EnterFunction(2);
>  	/* Compute size and mask */
>  	ip_vs_conn_tab_size = 1 << ip_vs_conn_tab_bits;
>  	ip_vs_conn_tab_mask = ip_vs_conn_tab_size - 1;
> @@ -1309,18 +1309,18 @@ int __init ip_vs_conn_init(void)
>  		rwlock_init(&__ip_vs_conntbl_lock_array[idx].l);
>  	}
> 
> -	retc = register_pernet_device(&ipvs_conn_ops);
> -
>  	/* calculate the random value for connection hash */
>  	get_random_bytes(&ip_vs_conn_rnd, sizeof(ip_vs_conn_rnd));
> +	LeaveFunction(2);
> 
> -	return retc;
> +	return 0;
>  }
> 
>  void ip_vs_conn_cleanup(void)
>  {
> -	unregister_pernet_device(&ipvs_conn_ops);
> +	EnterFunction(2);
>  	/* Release the empty cache */
>  	kmem_cache_destroy(ip_vs_conn_cachep);
>  	vfree(ip_vs_conn_tab);
> +	LeaveFunction(2);
>  }
> diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
> index a7bb81d..dc27fdf 100644
> --- a/net/netfilter/ipvs/ip_vs_core.c
> +++ b/net/netfilter/ipvs/ip_vs_core.c
> @@ -1343,6 +1343,10 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
>  		return NF_ACCEPT; /* The packet looks wrong, ignore */
> 
>  	net = skb_net(skb);
> +	/* Name space in use ? */
> +	if (net->ipvs->throttle)
> +		return NF_ACCEPT;
> +
>  	pd = ip_vs_proto_data_get(net, cih->protocol);
>  	if (!pd)
>  		return NF_ACCEPT;
> @@ -1563,6 +1567,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
>  		}
> 
>  	net = skb_net(skb);
> +	if (net->ipvs->throttle)
> +		return NF_ACCEPT;
>  	/* Protocol supported? */
>  	pd = ip_vs_proto_data_get(net, iph.protocol);
>  	if (unlikely(!pd))
> @@ -1588,7 +1594,6 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
>  	}
> 
>  	IP_VS_DBG_PKT(11, af, pp, skb, 0, "Incoming packet");
> -	net = skb_net(skb);
>  	ipvs = net_ipvs(net);
>  	/* Check the server status */
>  	if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) {
> @@ -1879,24 +1884,73 @@ static int __net_init __ip_vs_init(struct net *net)
>  {
>  	struct netns_ipvs *ipvs;
> 
> +	EnterFunction(2);
>  	ipvs = net_generic(net, ip_vs_net_id);
>  	if (ipvs == NULL) {
>  		pr_err("%s(): no memory.\n", __func__);
>  		return -ENOMEM;
>  	}
> +	/* Hold the beast until a service is registerd */
> +	ipvs->throttle = -1;
>  	ipvs->net = net;
>  	/* Counters used for creating unique names */
>  	ipvs->gen = atomic_read(&ipvs_netns_cnt);
>  	atomic_inc(&ipvs_netns_cnt);
>  	net->ipvs = ipvs;
> +
> +	if ( __ip_vs_estimator_init(net) < 0)
> +		goto estimator_fail;
> +
> +	if (__ip_vs_control_init(net) < 0)
> +		goto control_fail;
> +
> +	if (__ip_vs_protocol_init(net) < 0)
> +		goto protocol_fail;
> +
> +	if (__ip_vs_app_init(net) < 0)
> +		goto app_fail;
> +
> +	if (__ip_vs_conn_init(net) < 0)
> +		goto conn_fail;
> +
> +	if (__ip_vs_sync_init(net) < 0)
> +		goto sync_fail;
> +
> +	LeaveFunction(2);
>  	printk(KERN_INFO "IPVS: Creating netns size=%zu id=%d\n",
>  			 sizeof(struct netns_ipvs), ipvs->gen);
>  	return 0;
> +/*
> + * Error handling
> + */
> +
> +sync_fail:
> +	__ip_vs_conn_cleanup(net);
> +conn_fail:
> +	__ip_vs_app_cleanup(net);
> +app_fail:
> +	__ip_vs_protocol_cleanup(net);
> +protocol_fail:
> +	__ip_vs_control_cleanup(net);
> +control_fail:
> +	__ip_vs_estimator_cleanup(net);
> +estimator_fail:
> +	return -ENOMEM;
>  }
> 
>  static void __net_exit __ip_vs_cleanup(struct net *net)
>  {
> -	IP_VS_DBG(10, "ipvs netns %d released\n", net_ipvs(net)->gen);
> +	net->ipvs->throttle = -1;
> +	EnterFunction(2);
> +	__ip_vs_sync_cleanup(net);
> +	__ip_vs_service_cleanup(net);	/* ip_vs_flush() with locks */
> +	__ip_vs_conn_cleanup(net);
> +	__ip_vs_app_cleanup(net);
> +	__ip_vs_protocol_cleanup(net);
> +	__ip_vs_control_cleanup(net);
> +	__ip_vs_estimator_cleanup(net);
> +	LeaveFunction(2);
> +	IP_VS_DBG(2, "ipvs netns %d released\n", net_ipvs(net)->gen);
>  }
> 
>  static struct pernet_operations ipvs_core_ops = {
> @@ -1913,10 +1967,7 @@ static int __init ip_vs_init(void)
>  {
>  	int ret;
> 
> -	ret = register_pernet_device(&ipvs_core_ops);	/* Alloc ip_vs struct */
> -	if (ret < 0)
> -		return ret;
> -
> +	EnterFunction(2);
>  	ip_vs_estimator_init();
>  	ret = ip_vs_control_init();
>  	if (ret < 0) {
> @@ -1944,41 +1995,50 @@ static int __init ip_vs_init(void)
>  		goto cleanup_conn;
>  	}
> 
> +	ret = register_pernet_device(&ipvs_core_ops);	/* Alloc ip_vs struct */
> +	if (ret < 0)
> +		goto cleanup_sync;
> +
>  	ret = nf_register_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
>  	if (ret < 0) {
>  		pr_err("can't register hooks.\n");
> -		goto cleanup_sync;
> +		goto cleanup_net;
>  	}
> 
>  	pr_info("ipvs loaded.\n");
> +	LeaveFunction(2);
> +
>  	return ret;
> 
> +cleanup_net:
> +	unregister_pernet_device(&ipvs_core_ops);       /* free ip_vs struct */
>  cleanup_sync:
>  	ip_vs_sync_cleanup();
> -  cleanup_conn:
> +cleanup_conn:
>  	ip_vs_conn_cleanup();
> -  cleanup_app:
> +cleanup_app:
>  	ip_vs_app_cleanup();
> -  cleanup_protocol:
> +cleanup_protocol:
>  	ip_vs_protocol_cleanup();
>  	ip_vs_control_cleanup();
> -  cleanup_estimator:
> +cleanup_estimator:
>  	ip_vs_estimator_cleanup();
> -	unregister_pernet_device(&ipvs_core_ops);	/* free ip_vs struct */
>  	return ret;

While I do prefer labels to be in column 0, putting those changes
here is rather a lot of noise. Could you put them in a separate patch?

>  }
> 
>  static void __exit ip_vs_cleanup(void)
>  {
> +	EnterFunction(2);
>  	nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
> +	unregister_pernet_device(&ipvs_core_ops);	/* free ip_vs struct */
>  	ip_vs_sync_cleanup();
>  	ip_vs_conn_cleanup();
>  	ip_vs_app_cleanup();
>  	ip_vs_protocol_cleanup();
>  	ip_vs_control_cleanup();
>  	ip_vs_estimator_cleanup();
> -	unregister_pernet_device(&ipvs_core_ops);	/* free ip_vs struct */
>  	pr_info("ipvs unloaded.\n");
> +	LeaveFunction(2);
>  }
> 
>  module_init(ip_vs_init);
> diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
> index 08715d8..6534ca3 100644
> --- a/net/netfilter/ipvs/ip_vs_ctl.c
> +++ b/net/netfilter/ipvs/ip_vs_ctl.c
> @@ -69,6 +69,11 @@ int ip_vs_get_debug_level(void)
>  }
>  #endif
> 
> +
> +/*  Protos */
> +static void __ip_vs_del_service(struct ip_vs_service *svc);
> +
> +
>  #ifdef CONFIG_IP_VS_IPV6
>  /* Taken from rt6_fill_node() in net/ipv6/route.c, is there a better way? */
>  static int __ip_vs_addr_is_local_v6(struct net *net,
> @@ -345,6 +350,9 @@ static int ip_vs_svc_unhash(struct ip_vs_service *svc)
> 
>  	svc->flags &= ~IP_VS_SVC_F_HASHED;
>  	atomic_dec(&svc->refcnt);
> +	/* No more services then no need for input */
> +	if (atomic_read(&svc->refcnt) == 0)
> +		svc->net->ipvs->throttle = -1;
>  	return 1;
>  }
> 
> @@ -480,7 +488,6 @@ __ip_vs_unbind_svc(struct ip_vs_dest *dest)
>  	}
>  }
> 
> -

I don't think this hunk is appropriate for this patch.

>  /*
>   *	Returns hash value for real service
>   */
> @@ -1214,6 +1221,8 @@ ip_vs_add_service(struct net *net, struct ip_vs_service_user_kern *u,
>  	write_unlock_bh(&__ip_vs_svc_lock);
> 
>  	*svc_p = svc;
> +	/* Now whe have a service - full throttle */
> +	ipvs->throttle = 0;
>  	return 0;
> 
> 
> @@ -1472,6 +1481,41 @@ static int ip_vs_flush(struct net *net)
>  	return 0;
>  }
> 
> +/*
> + *	Delete service by {netns} in the service table.
> + *	Called by __ip_vs_cleanup()
> + */
> +void __ip_vs_service_cleanup(struct net *net)
> +{
> +	unsigned hash;
> +	struct ip_vs_service *svc, *tmp;
> +
> +	EnterFunction(2);
> +	/* Check for "full" addressed entries */
> +	for (hash = 0; hash<IP_VS_SVC_TAB_SIZE; hash++) {

A space is needed on either side of '<'

> +		write_lock_bh(&__ip_vs_svc_lock);
> +		list_for_each_entry_safe(svc, tmp, &ip_vs_svc_table[hash],
> +					 s_list) {
> +			if (net_eq(svc->net, net)) {
> +				ip_vs_svc_unhash(svc);
> +				/*  Wait until all the svc users go away. */
> +				IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0);
> +				__ip_vs_del_service(svc);
> +			}
> +		}
> +		list_for_each_entry_safe(svc, tmp, &ip_vs_svc_fwm_table[hash],
> +					 f_list) {
> +			if (net_eq(svc->net, net)) {
> +				ip_vs_svc_unhash(svc);
> +				/*  Wait until all the svc users go away. */
> +				IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0);
> +				__ip_vs_del_service(svc);
> +			}
> +		}
> +		write_unlock_bh(&__ip_vs_svc_lock);
> +	}
> +	LeaveFunction(2);
> +}
> 
>  /*
>   *	Zero counters in a service or all services
> @@ -3593,6 +3637,7 @@ int __net_init __ip_vs_control_init(struct net *net)
>  	int idx;
>  	struct netns_ipvs *ipvs = net_ipvs(net);
> 
> +	EnterFunction(2);
>  	ipvs->rs_lock = __RW_LOCK_UNLOCKED(ipvs->rs_lock);
> 
>  	/* Initialize rs_table */
> @@ -3619,6 +3664,7 @@ int __net_init __ip_vs_control_init(struct net *net)
>  	if (__ip_vs_control_init_sysctl(net))
>  		goto err;
> 
> +	LeaveFunction(2);
>  	return 0;
> 
>  err:
> @@ -3626,10 +3672,11 @@ err:
>  	return -ENOMEM;
>  }
> 
> -static void __net_exit __ip_vs_control_cleanup(struct net *net)
> +void __net_exit __ip_vs_control_cleanup(struct net *net)
>  {
>  	struct netns_ipvs *ipvs = net_ipvs(net);
> 
> +	EnterFunction(2);
>  	ip_vs_trash_cleanup(net);
>  	ip_vs_stop_estimator(net, &ipvs->tot_stats);
>  	__ip_vs_control_cleanup_sysctl(net);
> @@ -3637,13 +3684,9 @@ static void __net_exit __ip_vs_control_cleanup(struct net *net)
>  	proc_net_remove(net, "ip_vs_stats");
>  	proc_net_remove(net, "ip_vs");
>  	free_percpu(ipvs->tot_stats.cpustats);
> +	LeaveFunction(2);
>  }
> 
> -static struct pernet_operations ipvs_control_ops = {
> -	.init = __ip_vs_control_init,
> -	.exit = __ip_vs_control_cleanup,
> -};
> -
>  int __init ip_vs_control_init(void)
>  {
>  	int idx;
> @@ -3657,12 +3700,6 @@ int __init ip_vs_control_init(void)
>  		INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]);
>  	}
> 
> -	ret = register_pernet_device(&ipvs_control_ops);
> -	if (ret) {
> -		pr_err("cannot register namespace.\n");
> -		goto err;
> -	}
> -
>  	smp_wmb();	/* Do we really need it now ? */
> 
>  	ret = nf_register_sockopt(&ip_vs_sockopts);
> @@ -3682,8 +3719,6 @@ int __init ip_vs_control_init(void)
>  	return 0;
> 
>  err_net:
> -	unregister_pernet_device(&ipvs_control_ops);
> -err:
>  	return ret;
>  }
> 
> @@ -3691,7 +3726,6 @@ err:
>  void ip_vs_control_cleanup(void)
>  {
>  	EnterFunction(2);
> -	unregister_pernet_device(&ipvs_control_ops);
>  	ip_vs_genl_unregister();
>  	nf_unregister_sockopt(&ip_vs_sockopts);
>  	LeaveFunction(2);
> diff --git a/net/netfilter/ipvs/ip_vs_est.c b/net/netfilter/ipvs/ip_vs_est.c
> index 759163e..508cce9 100644
> --- a/net/netfilter/ipvs/ip_vs_est.c
> +++ b/net/netfilter/ipvs/ip_vs_est.c
> @@ -192,7 +192,7 @@ void ip_vs_read_estimator(struct ip_vs_stats_user *dst,
>  	dst->outbps = (e->outbps + 0xF) >> 5;
>  }
> 
> -static int __net_init __ip_vs_estimator_init(struct net *net)
> +int __net_init __ip_vs_estimator_init(struct net *net)
>  {
>  	struct netns_ipvs *ipvs = net_ipvs(net);
> 
> @@ -203,24 +203,16 @@ static int __net_init __ip_vs_estimator_init(struct net *net)
>  	return 0;
>  }
> 
> -static void __net_exit __ip_vs_estimator_exit(struct net *net)
> +void __net_exit __ip_vs_estimator_cleanup(struct net *net)
>  {
>  	del_timer_sync(&net_ipvs(net)->est_timer);
>  }
> -static struct pernet_operations ip_vs_app_ops = {
> -	.init = __ip_vs_estimator_init,
> -	.exit = __ip_vs_estimator_exit,
> -};
> 
>  int __init ip_vs_estimator_init(void)
>  {
> -	int rv;
> -
> -	rv = register_pernet_device(&ip_vs_app_ops);
> -	return rv;
> +	return 0;
>  }
> 
>  void ip_vs_estimator_cleanup(void)
>  {
> -	unregister_pernet_device(&ip_vs_app_ops);
>  }
> diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c
> index f7021fc..eb86028 100644
> --- a/net/netfilter/ipvs/ip_vs_proto.c
> +++ b/net/netfilter/ipvs/ip_vs_proto.c
> @@ -316,7 +316,7 @@ ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp,
>  /*
>   * per network name-space init
>   */
> -static int __net_init __ip_vs_protocol_init(struct net *net)
> +int __net_init __ip_vs_protocol_init(struct net *net)
>  {
>  #ifdef CONFIG_IP_VS_PROTO_TCP
>  	register_ip_vs_proto_netns(net, &ip_vs_protocol_tcp);
> @@ -336,7 +336,7 @@ static int __net_init __ip_vs_protocol_init(struct net *net)
>  	return 0;
>  }
> 
> -static void __net_exit __ip_vs_protocol_cleanup(struct net *net)
> +void __net_exit __ip_vs_protocol_cleanup(struct net *net)
>  {
>  	struct netns_ipvs *ipvs = net_ipvs(net);
>  	struct ip_vs_proto_data *pd;
> @@ -349,11 +349,6 @@ static void __net_exit __ip_vs_protocol_cleanup(struct net *net)
>  	}
>  }
> 
> -static struct pernet_operations ipvs_proto_ops = {
> -	.init = __ip_vs_protocol_init,
> -	.exit = __ip_vs_protocol_cleanup,
> -};
> -
>  int __init ip_vs_protocol_init(void)
>  {
>  	char protocols[64];
> @@ -382,7 +377,6 @@ int __init ip_vs_protocol_init(void)
>  	REGISTER_PROTOCOL(&ip_vs_protocol_esp);
>  #endif
>  	pr_info("Registered protocols (%s)\n", &protocols[2]);
> -	return register_pernet_device(&ipvs_proto_ops);
> 
>  	return 0;
>  }
> @@ -393,7 +387,6 @@ void ip_vs_protocol_cleanup(void)
>  	struct ip_vs_protocol *pp;
>  	int i;
> 
> -	unregister_pernet_device(&ipvs_proto_ops);
>  	/* unregister all the ipvs protocols */
>  	for (i = 0; i < IP_VS_PROTO_TAB_SIZE; i++) {
>  		while ((pp = ip_vs_proto_table[i]) != NULL)
> diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
> index 1aeca1d..e911f03 100644
> --- a/net/netfilter/ipvs/ip_vs_sync.c
> +++ b/net/netfilter/ipvs/ip_vs_sync.c
> @@ -1664,7 +1664,7 @@ int stop_sync_thread(struct net *net, int state)
>  /*
>   * Initialize data struct for each netns
>   */
> -static int __net_init __ip_vs_sync_init(struct net *net)
> +int __net_init __ip_vs_sync_init(struct net *net)
>  {
>  	struct netns_ipvs *ipvs = net_ipvs(net);
> 
> @@ -1678,24 +1678,17 @@ static int __net_init __ip_vs_sync_init(struct net *net)
>  	return 0;
>  }
> 
> -static void __ip_vs_sync_cleanup(struct net *net)
> +void __ip_vs_sync_cleanup(struct net *net)
>  {
>  	stop_sync_thread(net, IP_VS_STATE_MASTER);
>  	stop_sync_thread(net, IP_VS_STATE_BACKUP);
>  }
> 
> -static struct pernet_operations ipvs_sync_ops = {
> -	.init = __ip_vs_sync_init,
> -	.exit = __ip_vs_sync_cleanup,
> -};
> -
> -
>  int __init ip_vs_sync_init(void)
>  {
> -	return register_pernet_device(&ipvs_sync_ops);
> +	return 0;
>  }
> 
>  void ip_vs_sync_cleanup(void)
>  {
> -	unregister_pernet_device(&ipvs_sync_ops);
>  }
> --
> 1.7.2.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux