Blame view
ipc/ipc_sysctl.c
7.01 KB
a5494dcd8 [PATCH] sysctl: m... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/* * Copyright (C) 2007 * * Author: Eric Biederman <ebiederm@xmision.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, version 2 of the * License. */ #include <linux/module.h> #include <linux/ipc.h> #include <linux/nsproxy.h> #include <linux/sysctl.h> #include <linux/uaccess.h> |
ae5e1b22f namespaces: move ... |
17 |
#include <linux/ipc_namespace.h> |
6546bc427 ipc: re-enable ms... |
18 19 |
#include <linux/msg.h> #include "util.h" |
a5494dcd8 [PATCH] sysctl: m... |
20 |
|
a5494dcd8 [PATCH] sysctl: m... |
21 22 23 24 25 26 27 |
static void *get_ipc(ctl_table *table) { char *which = table->data; struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; which = (which - (char *)&init_ipc_ns) + (char *)ipc_ns; return which; } |
a5494dcd8 [PATCH] sysctl: m... |
28 |
|
11dea1900 proc_sysctl: use ... |
29 |
#ifdef CONFIG_PROC_SYSCTL |
8d65af789 sysctl: remove "s... |
30 |
static int proc_ipc_dointvec(ctl_table *table, int write, |
a5494dcd8 [PATCH] sysctl: m... |
31 32 33 |
void __user *buffer, size_t *lenp, loff_t *ppos) { struct ctl_table ipc_table; |
b34a6b1da ipc: introduce sh... |
34 |
|
a5494dcd8 [PATCH] sysctl: m... |
35 36 |
memcpy(&ipc_table, table, sizeof(ipc_table)); ipc_table.data = get_ipc(table); |
8d65af789 sysctl: remove "s... |
37 |
return proc_dointvec(&ipc_table, write, buffer, lenp, ppos); |
a5494dcd8 [PATCH] sysctl: m... |
38 |
} |
b34a6b1da ipc: introduce sh... |
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
static int proc_ipc_dointvec_minmax(ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { struct ctl_table ipc_table; memcpy(&ipc_table, table, sizeof(ipc_table)); ipc_table.data = get_ipc(table); return proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos); } static int proc_ipc_dointvec_minmax_orphans(ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { struct ipc_namespace *ns = current->nsproxy->ipc_ns; int err = proc_ipc_dointvec_minmax(table, write, buffer, lenp, ppos); if (err < 0) return err; if (ns->shm_rmid_forced) shm_destroy_orphaned(ns); return err; } |
9bf76ca32 ipc, msg: forbid ... |
62 |
static int proc_ipc_callback_dointvec_minmax(ctl_table *table, int write, |
8d65af789 sysctl: remove "s... |
63 |
void __user *buffer, size_t *lenp, loff_t *ppos) |
91cfb2b4b ipc: do not recom... |
64 |
{ |
6546bc427 ipc: re-enable ms... |
65 |
struct ctl_table ipc_table; |
91cfb2b4b ipc: do not recom... |
66 67 |
size_t lenp_bef = *lenp; int rc; |
6546bc427 ipc: re-enable ms... |
68 69 |
memcpy(&ipc_table, table, sizeof(ipc_table)); ipc_table.data = get_ipc(table); |
9bf76ca32 ipc, msg: forbid ... |
70 |
rc = proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos); |
91cfb2b4b ipc: do not recom... |
71 72 |
if (write && !rc && lenp_bef == *lenp) |
9eefe520c ipc: do not use a... |
73 74 75 76 77 78 |
/* * Tunable has successfully been changed by hand. Disable its * automatic adjustment. This simply requires unregistering * the notifiers that trigger recalculation. */ unregister_ipcns_notifier(current->nsproxy->ipc_ns); |
91cfb2b4b ipc: do not recom... |
79 80 81 |
return rc; } |
a5494dcd8 [PATCH] sysctl: m... |
82 |
static int proc_ipc_doulongvec_minmax(ctl_table *table, int write, |
8d65af789 sysctl: remove "s... |
83 |
void __user *buffer, size_t *lenp, loff_t *ppos) |
a5494dcd8 [PATCH] sysctl: m... |
84 85 86 87 |
{ struct ctl_table ipc_table; memcpy(&ipc_table, table, sizeof(ipc_table)); ipc_table.data = get_ipc(table); |
8d65af789 sysctl: remove "s... |
88 |
return proc_doulongvec_minmax(&ipc_table, write, buffer, |
a5494dcd8 [PATCH] sysctl: m... |
89 90 |
lenp, ppos); } |
4c2c3b4aa ipc/ipc_sysctl.c:... |
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
/* * Routine that is called when the file "auto_msgmni" has successfully been * written. * Two values are allowed: * 0: unregister msgmni's callback routine from the ipc namespace notifier * chain. This means that msgmni won't be recomputed anymore upon memory * add/remove or ipc namespace creation/removal. * 1: register back the callback routine. */ static void ipc_auto_callback(int val) { if (!val) unregister_ipcns_notifier(current->nsproxy->ipc_ns); else { /* * Re-enable automatic recomputing only if not already * enabled. */ recompute_msgmni(current->nsproxy->ipc_ns); cond_register_ipcns_notifier(current->nsproxy->ipc_ns); } } |
9eefe520c ipc: do not use a... |
113 |
static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write, |
8d65af789 sysctl: remove "s... |
114 |
void __user *buffer, size_t *lenp, loff_t *ppos) |
9eefe520c ipc: do not use a... |
115 116 117 118 119 120 121 122 123 |
{ struct ctl_table ipc_table; size_t lenp_bef = *lenp; int oldval; int rc; memcpy(&ipc_table, table, sizeof(ipc_table)); ipc_table.data = get_ipc(table); oldval = *((int *)(ipc_table.data)); |
8d65af789 sysctl: remove "s... |
124 |
rc = proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos); |
9eefe520c ipc: do not use a... |
125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
if (write && !rc && lenp_bef == *lenp) { int newval = *((int *)(ipc_table.data)); /* * The file "auto_msgmni" has correctly been set. * React by (un)registering the corresponding tunable, if the * value has changed. */ if (newval != oldval) ipc_auto_callback(newval); } return rc; } |
a5494dcd8 [PATCH] sysctl: m... |
139 140 141 |
#else #define proc_ipc_doulongvec_minmax NULL #define proc_ipc_dointvec NULL |
b34a6b1da ipc: introduce sh... |
142 143 |
#define proc_ipc_dointvec_minmax NULL #define proc_ipc_dointvec_minmax_orphans NULL |
9bf76ca32 ipc, msg: forbid ... |
144 |
#define proc_ipc_callback_dointvec_minmax NULL |
9eefe520c ipc: do not use a... |
145 |
#define proc_ipcauto_dointvec_minmax NULL |
a5494dcd8 [PATCH] sysctl: m... |
146 |
#endif |
9eefe520c ipc: do not use a... |
147 148 |
static int zero; static int one = 1; |
03f595668 ipc: add sysctl t... |
149 |
static int int_max = INT_MAX; |
9eefe520c ipc: do not use a... |
150 |
|
a5494dcd8 [PATCH] sysctl: m... |
151 152 |
static struct ctl_table ipc_kern_table[] = { { |
a5494dcd8 [PATCH] sysctl: m... |
153 154 |
.procname = "shmmax", .data = &init_ipc_ns.shm_ctlmax, |
239521f31 ipc: whitespace c... |
155 |
.maxlen = sizeof(init_ipc_ns.shm_ctlmax), |
a5494dcd8 [PATCH] sysctl: m... |
156 157 |
.mode = 0644, .proc_handler = proc_ipc_doulongvec_minmax, |
a5494dcd8 [PATCH] sysctl: m... |
158 159 |
}, { |
a5494dcd8 [PATCH] sysctl: m... |
160 161 |
.procname = "shmall", .data = &init_ipc_ns.shm_ctlall, |
239521f31 ipc: whitespace c... |
162 |
.maxlen = sizeof(init_ipc_ns.shm_ctlall), |
a5494dcd8 [PATCH] sysctl: m... |
163 164 |
.mode = 0644, .proc_handler = proc_ipc_doulongvec_minmax, |
a5494dcd8 [PATCH] sysctl: m... |
165 166 |
}, { |
a5494dcd8 [PATCH] sysctl: m... |
167 168 |
.procname = "shmmni", .data = &init_ipc_ns.shm_ctlmni, |
239521f31 ipc: whitespace c... |
169 |
.maxlen = sizeof(init_ipc_ns.shm_ctlmni), |
a5494dcd8 [PATCH] sysctl: m... |
170 171 |
.mode = 0644, .proc_handler = proc_ipc_dointvec, |
a5494dcd8 [PATCH] sysctl: m... |
172 173 |
}, { |
b34a6b1da ipc: introduce sh... |
174 175 176 177 178 179 180 181 182 |
.procname = "shm_rmid_forced", .data = &init_ipc_ns.shm_rmid_forced, .maxlen = sizeof(init_ipc_ns.shm_rmid_forced), .mode = 0644, .proc_handler = proc_ipc_dointvec_minmax_orphans, .extra1 = &zero, .extra2 = &one, }, { |
a5494dcd8 [PATCH] sysctl: m... |
183 184 |
.procname = "msgmax", .data = &init_ipc_ns.msg_ctlmax, |
239521f31 ipc: whitespace c... |
185 |
.maxlen = sizeof(init_ipc_ns.msg_ctlmax), |
a5494dcd8 [PATCH] sysctl: m... |
186 |
.mode = 0644, |
9bf76ca32 ipc, msg: forbid ... |
187 188 189 |
.proc_handler = proc_ipc_dointvec_minmax, .extra1 = &zero, .extra2 = &int_max, |
a5494dcd8 [PATCH] sysctl: m... |
190 191 |
}, { |
a5494dcd8 [PATCH] sysctl: m... |
192 193 |
.procname = "msgmni", .data = &init_ipc_ns.msg_ctlmni, |
239521f31 ipc: whitespace c... |
194 |
.maxlen = sizeof(init_ipc_ns.msg_ctlmni), |
a5494dcd8 [PATCH] sysctl: m... |
195 |
.mode = 0644, |
9bf76ca32 ipc, msg: forbid ... |
196 197 198 |
.proc_handler = proc_ipc_callback_dointvec_minmax, .extra1 = &zero, .extra2 = &int_max, |
a5494dcd8 [PATCH] sysctl: m... |
199 200 |
}, { |
a5494dcd8 [PATCH] sysctl: m... |
201 202 |
.procname = "msgmnb", .data = &init_ipc_ns.msg_ctlmnb, |
239521f31 ipc: whitespace c... |
203 |
.maxlen = sizeof(init_ipc_ns.msg_ctlmnb), |
a5494dcd8 [PATCH] sysctl: m... |
204 |
.mode = 0644, |
9bf76ca32 ipc, msg: forbid ... |
205 206 207 |
.proc_handler = proc_ipc_dointvec_minmax, .extra1 = &zero, .extra2 = &int_max, |
a5494dcd8 [PATCH] sysctl: m... |
208 209 |
}, { |
a5494dcd8 [PATCH] sysctl: m... |
210 211 |
.procname = "sem", .data = &init_ipc_ns.sem_ctls, |
239521f31 ipc: whitespace c... |
212 |
.maxlen = 4*sizeof(int), |
a5494dcd8 [PATCH] sysctl: m... |
213 214 |
.mode = 0644, .proc_handler = proc_ipc_dointvec, |
a5494dcd8 [PATCH] sysctl: m... |
215 |
}, |
9eefe520c ipc: do not use a... |
216 |
{ |
9eefe520c ipc: do not use a... |
217 218 219 220 221 222 223 224 |
.procname = "auto_msgmni", .data = &init_ipc_ns.auto_msgmni, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_ipcauto_dointvec_minmax, .extra1 = &zero, .extra2 = &one, }, |
03f595668 ipc: add sysctl t... |
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
#ifdef CONFIG_CHECKPOINT_RESTORE { .procname = "sem_next_id", .data = &init_ipc_ns.ids[IPC_SEM_IDS].next_id, .maxlen = sizeof(init_ipc_ns.ids[IPC_SEM_IDS].next_id), .mode = 0644, .proc_handler = proc_ipc_dointvec_minmax, .extra1 = &zero, .extra2 = &int_max, }, { .procname = "msg_next_id", .data = &init_ipc_ns.ids[IPC_MSG_IDS].next_id, .maxlen = sizeof(init_ipc_ns.ids[IPC_MSG_IDS].next_id), .mode = 0644, .proc_handler = proc_ipc_dointvec_minmax, .extra1 = &zero, .extra2 = &int_max, }, { .procname = "shm_next_id", .data = &init_ipc_ns.ids[IPC_SHM_IDS].next_id, .maxlen = sizeof(init_ipc_ns.ids[IPC_SHM_IDS].next_id), .mode = 0644, .proc_handler = proc_ipc_dointvec_minmax, .extra1 = &zero, .extra2 = &int_max, }, #endif |
a5494dcd8 [PATCH] sysctl: m... |
254 255 256 257 258 |
{} }; static struct ctl_table ipc_root_table[] = { { |
a5494dcd8 [PATCH] sysctl: m... |
259 260 261 262 263 264 265 266 267 |
.procname = "kernel", .mode = 0555, .child = ipc_kern_table, }, {} }; static int __init ipc_sysctl_init(void) { |
0b4d41471 [PATCH] sysctl: r... |
268 |
register_sysctl_table(ipc_root_table); |
a5494dcd8 [PATCH] sysctl: m... |
269 270 |
return 0; } |
6d08a2567 ipc: use device_i... |
271 |
device_initcall(ipc_sysctl_init); |