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 lvs-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
|