aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNadia Derbey <Nadia.Derbey@bull.net>2008-04-29 04:00:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:06:13 -0400
commit91cfb2b4b57816de0c96de417b3238249f0b125f (patch)
treea7f10f4445c6ffeec0e4cad5a2ea5dae3d0faf8b
parente2c284d8a87f95df9b47c6a13168a844ca7c03e9 (diff)
ipc: do not recompute msgmni anymore if explicitly set by user
Make msgmni not recomputed anymore upon ipc namespace creation / removal or memory add/remove, as soon as it has been set from userland. As soon as msgmni is explicitly set via procfs or sysctl(), the associated callback routine is unregistered from the ipc namespace notifier chain. Signed-off-by: Nadia Derbey <Nadia.Derbey@bull.net> Cc: Yasunori Goto <y-goto@jp.fujitsu.com> Cc: Matt Helsley <matthltc@us.ibm.com> Cc: Mingming Cao <cmm@us.ibm.com> Cc: Pierre Peiffer <pierre.peiffer@bull.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--ipc/ipc_sysctl.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/ipc/ipc_sysctl.c b/ipc/ipc_sysctl.c
index 7f4235bed51b..d12ff5cd2a0b 100644
--- a/ipc/ipc_sysctl.c
+++ b/ipc/ipc_sysctl.c
@@ -35,6 +35,24 @@ static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp,
35 return proc_dointvec(&ipc_table, write, filp, buffer, lenp, ppos); 35 return proc_dointvec(&ipc_table, write, filp, buffer, lenp, ppos);
36} 36}
37 37
38static int proc_ipc_callback_dointvec(ctl_table *table, int write,
39 struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
40{
41 size_t lenp_bef = *lenp;
42 int rc;
43
44 rc = proc_ipc_dointvec(table, write, filp, buffer, lenp, ppos);
45
46 if (write && !rc && lenp_bef == *lenp)
47 /*
48 * Tunable has successfully been changed from userland:
49 * disable its automatic recomputing.
50 */
51 unregister_ipcns_notifier(current->nsproxy->ipc_ns);
52
53 return rc;
54}
55
38static int proc_ipc_doulongvec_minmax(ctl_table *table, int write, 56static int proc_ipc_doulongvec_minmax(ctl_table *table, int write,
39 struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) 57 struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
40{ 58{
@@ -49,6 +67,7 @@ static int proc_ipc_doulongvec_minmax(ctl_table *table, int write,
49#else 67#else
50#define proc_ipc_doulongvec_minmax NULL 68#define proc_ipc_doulongvec_minmax NULL
51#define proc_ipc_dointvec NULL 69#define proc_ipc_dointvec NULL
70#define proc_ipc_callback_dointvec NULL
52#endif 71#endif
53 72
54#ifdef CONFIG_SYSCTL_SYSCALL 73#ifdef CONFIG_SYSCTL_SYSCALL
@@ -90,8 +109,28 @@ static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen,
90 } 109 }
91 return 1; 110 return 1;
92} 111}
112
113static int sysctl_ipc_registered_data(ctl_table *table, int __user *name,
114 int nlen, void __user *oldval, size_t __user *oldlenp,
115 void __user *newval, size_t newlen)
116{
117 int rc;
118
119 rc = sysctl_ipc_data(table, name, nlen, oldval, oldlenp, newval,
120 newlen);
121
122 if (newval && newlen && rc > 0)
123 /*
124 * Tunable has successfully been changed from userland:
125 * disable its automatic recomputing.
126 */
127 unregister_ipcns_notifier(current->nsproxy->ipc_ns);
128
129 return rc;
130}
93#else 131#else
94#define sysctl_ipc_data NULL 132#define sysctl_ipc_data NULL
133#define sysctl_ipc_registered_data NULL
95#endif 134#endif
96 135
97static struct ctl_table ipc_kern_table[] = { 136static struct ctl_table ipc_kern_table[] = {
@@ -137,8 +176,8 @@ static struct ctl_table ipc_kern_table[] = {
137 .data = &init_ipc_ns.msg_ctlmni, 176 .data = &init_ipc_ns.msg_ctlmni,
138 .maxlen = sizeof (init_ipc_ns.msg_ctlmni), 177 .maxlen = sizeof (init_ipc_ns.msg_ctlmni),
139 .mode = 0644, 178 .mode = 0644,
140 .proc_handler = proc_ipc_dointvec, 179 .proc_handler = proc_ipc_callback_dointvec,
141 .strategy = sysctl_ipc_data, 180 .strategy = sysctl_ipc_registered_data,
142 }, 181 },
143 { 182 {
144 .ctl_name = KERN_MSGMNB, 183 .ctl_name = KERN_MSGMNB,