diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2008-05-19 16:49:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-05-19 16:49:52 -0400 |
commit | d5a4502e9efa534212484fd691339f6469cf95ff (patch) | |
tree | b1cfbcc8ced47a44c4f7d7492ddd29f598c24b6a | |
parent | d62c612ef8a66be534a3ada598cfa28d40cd0b3c (diff) |
netns: Register net/core/ sysctls at read-only root.
Most of the net/core/xxx sysctls are read-only now, but this
goal is achieved with excessive memory consumption in each
namespace - the whole table is cloned and most of the entries
in it are ~= 0222.
Split it into two parts and register (the largest) one at the
read-only root.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/core/sysctl_net_core.c | 39 |
1 files changed, 19 insertions, 20 deletions
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index 5fc801057244..a570e2af22cb 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c | |||
@@ -125,14 +125,6 @@ static struct ctl_table net_core_table[] = { | |||
125 | #endif /* CONFIG_XFRM */ | 125 | #endif /* CONFIG_XFRM */ |
126 | #endif /* CONFIG_NET */ | 126 | #endif /* CONFIG_NET */ |
127 | { | 127 | { |
128 | .ctl_name = NET_CORE_SOMAXCONN, | ||
129 | .procname = "somaxconn", | ||
130 | .data = &init_net.core.sysctl_somaxconn, | ||
131 | .maxlen = sizeof(int), | ||
132 | .mode = 0644, | ||
133 | .proc_handler = &proc_dointvec | ||
134 | }, | ||
135 | { | ||
136 | .ctl_name = NET_CORE_BUDGET, | 128 | .ctl_name = NET_CORE_BUDGET, |
137 | .procname = "netdev_budget", | 129 | .procname = "netdev_budget", |
138 | .data = &netdev_budget, | 130 | .data = &netdev_budget, |
@@ -151,6 +143,18 @@ static struct ctl_table net_core_table[] = { | |||
151 | { .ctl_name = 0 } | 143 | { .ctl_name = 0 } |
152 | }; | 144 | }; |
153 | 145 | ||
146 | static struct ctl_table netns_core_table[] = { | ||
147 | { | ||
148 | .ctl_name = NET_CORE_SOMAXCONN, | ||
149 | .procname = "somaxconn", | ||
150 | .data = &init_net.core.sysctl_somaxconn, | ||
151 | .maxlen = sizeof(int), | ||
152 | .mode = 0644, | ||
153 | .proc_handler = &proc_dointvec | ||
154 | }, | ||
155 | { .ctl_name = 0 } | ||
156 | }; | ||
157 | |||
154 | static __net_initdata struct ctl_path net_core_path[] = { | 158 | static __net_initdata struct ctl_path net_core_path[] = { |
155 | { .procname = "net", .ctl_name = CTL_NET, }, | 159 | { .procname = "net", .ctl_name = CTL_NET, }, |
156 | { .procname = "core", .ctl_name = NET_CORE, }, | 160 | { .procname = "core", .ctl_name = NET_CORE, }, |
@@ -159,23 +163,17 @@ static __net_initdata struct ctl_path net_core_path[] = { | |||
159 | 163 | ||
160 | static __net_init int sysctl_core_net_init(struct net *net) | 164 | static __net_init int sysctl_core_net_init(struct net *net) |
161 | { | 165 | { |
162 | struct ctl_table *tbl, *tmp; | 166 | struct ctl_table *tbl; |
163 | 167 | ||
164 | net->core.sysctl_somaxconn = SOMAXCONN; | 168 | net->core.sysctl_somaxconn = SOMAXCONN; |
165 | 169 | ||
166 | tbl = net_core_table; | 170 | tbl = netns_core_table; |
167 | if (net != &init_net) { | 171 | if (net != &init_net) { |
168 | tbl = kmemdup(tbl, sizeof(net_core_table), GFP_KERNEL); | 172 | tbl = kmemdup(tbl, sizeof(netns_core_table), GFP_KERNEL); |
169 | if (tbl == NULL) | 173 | if (tbl == NULL) |
170 | goto err_dup; | 174 | goto err_dup; |
171 | 175 | ||
172 | for (tmp = tbl; tmp->procname; tmp++) { | 176 | tbl[0].data = &net->core.sysctl_somaxconn; |
173 | if (tmp->data >= (void *)&init_net && | ||
174 | tmp->data < (void *)(&init_net + 1)) | ||
175 | tmp->data += (char *)net - (char *)&init_net; | ||
176 | else | ||
177 | tmp->mode &= ~0222; | ||
178 | } | ||
179 | } | 177 | } |
180 | 178 | ||
181 | net->core.sysctl_hdr = register_net_sysctl_table(net, | 179 | net->core.sysctl_hdr = register_net_sysctl_table(net, |
@@ -186,7 +184,7 @@ static __net_init int sysctl_core_net_init(struct net *net) | |||
186 | return 0; | 184 | return 0; |
187 | 185 | ||
188 | err_reg: | 186 | err_reg: |
189 | if (tbl != net_core_table) | 187 | if (tbl != netns_core_table) |
190 | kfree(tbl); | 188 | kfree(tbl); |
191 | err_dup: | 189 | err_dup: |
192 | return -ENOMEM; | 190 | return -ENOMEM; |
@@ -198,7 +196,7 @@ static __net_exit void sysctl_core_net_exit(struct net *net) | |||
198 | 196 | ||
199 | tbl = net->core.sysctl_hdr->ctl_table_arg; | 197 | tbl = net->core.sysctl_hdr->ctl_table_arg; |
200 | unregister_net_sysctl_table(net->core.sysctl_hdr); | 198 | unregister_net_sysctl_table(net->core.sysctl_hdr); |
201 | BUG_ON(tbl == net_core_table); | 199 | BUG_ON(tbl == netns_core_table); |
202 | kfree(tbl); | 200 | kfree(tbl); |
203 | } | 201 | } |
204 | 202 | ||
@@ -209,6 +207,7 @@ static __net_initdata struct pernet_operations sysctl_core_ops = { | |||
209 | 207 | ||
210 | static __init int sysctl_core_init(void) | 208 | static __init int sysctl_core_init(void) |
211 | { | 209 | { |
210 | register_net_sysctl_rotable(net_core_path, net_core_table); | ||
212 | return register_pernet_subsys(&sysctl_core_ops); | 211 | return register_pernet_subsys(&sysctl_core_ops); |
213 | } | 212 | } |
214 | 213 | ||