|
@@ -70,7 +70,6 @@
|
|
|
* entries that haven't been touched for a day.
|
|
|
*/
|
|
|
#define COUNT_FOR_FULL_EXPIRATION 30
|
|
|
-static int sysctl_ip_vs_lblc_expiration = 24*60*60*HZ;
|
|
|
|
|
|
|
|
|
/*
|
|
@@ -117,7 +116,7 @@ struct ip_vs_lblc_table {
|
|
|
static ctl_table vs_vars_table[] = {
|
|
|
{
|
|
|
.procname = "lblc_expiration",
|
|
|
- .data = &sysctl_ip_vs_lblc_expiration,
|
|
|
+ .data = NULL,
|
|
|
.maxlen = sizeof(int),
|
|
|
.mode = 0644,
|
|
|
.proc_handler = proc_dointvec_jiffies,
|
|
@@ -125,8 +124,6 @@ static ctl_table vs_vars_table[] = {
|
|
|
{ }
|
|
|
};
|
|
|
|
|
|
-static struct ctl_table_header * sysctl_header;
|
|
|
-
|
|
|
static inline void ip_vs_lblc_free(struct ip_vs_lblc_entry *en)
|
|
|
{
|
|
|
list_del(&en->list);
|
|
@@ -248,6 +245,7 @@ static inline void ip_vs_lblc_full_check(struct ip_vs_service *svc)
|
|
|
struct ip_vs_lblc_entry *en, *nxt;
|
|
|
unsigned long now = jiffies;
|
|
|
int i, j;
|
|
|
+ struct netns_ipvs *ipvs = net_ipvs(svc->net);
|
|
|
|
|
|
for (i=0, j=tbl->rover; i<IP_VS_LBLC_TAB_SIZE; i++) {
|
|
|
j = (j + 1) & IP_VS_LBLC_TAB_MASK;
|
|
@@ -255,7 +253,8 @@ static inline void ip_vs_lblc_full_check(struct ip_vs_service *svc)
|
|
|
write_lock(&svc->sched_lock);
|
|
|
list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) {
|
|
|
if (time_before(now,
|
|
|
- en->lastuse + sysctl_ip_vs_lblc_expiration))
|
|
|
+ en->lastuse +
|
|
|
+ ipvs->sysctl_lblc_expiration))
|
|
|
continue;
|
|
|
|
|
|
ip_vs_lblc_free(en);
|
|
@@ -548,23 +547,43 @@ static struct ip_vs_scheduler ip_vs_lblc_scheduler =
|
|
|
*/
|
|
|
static int __net_init __ip_vs_lblc_init(struct net *net)
|
|
|
{
|
|
|
- if (!net_eq(net, &init_net)) /* netns not enabled yet */
|
|
|
- return -EPERM;
|
|
|
-
|
|
|
- sysctl_header = register_net_sysctl_table(net, net_vs_ctl_path,
|
|
|
- vs_vars_table);
|
|
|
- if (!sysctl_header)
|
|
|
- return -ENOMEM;
|
|
|
+ struct netns_ipvs *ipvs = net_ipvs(net);
|
|
|
+
|
|
|
+ if (!net_eq(net, &init_net)) {
|
|
|
+ ipvs->lblc_ctl_table = kmemdup(vs_vars_table,
|
|
|
+ sizeof(vs_vars_table),
|
|
|
+ GFP_KERNEL);
|
|
|
+ if (ipvs->lblc_ctl_table == NULL)
|
|
|
+ goto err_dup;
|
|
|
+ } else
|
|
|
+ ipvs->lblc_ctl_table = vs_vars_table;
|
|
|
+ ipvs->sysctl_lblc_expiration = 24*60*60*HZ;
|
|
|
+ ipvs->lblc_ctl_table[0].data = &ipvs->sysctl_lblc_expiration;
|
|
|
+
|
|
|
+ ipvs->lblc_ctl_header =
|
|
|
+ register_net_sysctl_table(net, net_vs_ctl_path,
|
|
|
+ ipvs->lblc_ctl_table);
|
|
|
+ if (!ipvs->lblc_ctl_header)
|
|
|
+ goto err_reg;
|
|
|
|
|
|
return 0;
|
|
|
+
|
|
|
+err_reg:
|
|
|
+ if (!net_eq(net, &init_net))
|
|
|
+ kfree(ipvs->lblc_ctl_table);
|
|
|
+
|
|
|
+err_dup:
|
|
|
+ return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
static void __net_exit __ip_vs_lblc_exit(struct net *net)
|
|
|
{
|
|
|
- if (!net_eq(net, &init_net)) /* netns not enabled yet */
|
|
|
- return;
|
|
|
+ struct netns_ipvs *ipvs = net_ipvs(net);
|
|
|
+
|
|
|
+ unregister_net_sysctl_table(ipvs->lblc_ctl_header);
|
|
|
|
|
|
- unregister_net_sysctl_table(sysctl_header);
|
|
|
+ if (!net_eq(net, &init_net))
|
|
|
+ kfree(ipvs->lblc_ctl_table);
|
|
|
}
|
|
|
|
|
|
static struct pernet_operations ip_vs_lblc_ops = {
|
|
@@ -586,7 +605,6 @@ static int __init ip_vs_lblc_init(void)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
static void __exit ip_vs_lblc_cleanup(void)
|
|
|
{
|
|
|
unregister_ip_vs_scheduler(&ip_vs_lblc_scheduler);
|