2 * sysctl.c: General linux system control interface
4 * Begun 24 March 1995, Stephen Tweedie
5 * Added /proc support, Dec 1995
6 * Added bdflush entry and intvec min/max checking, 2/23/96, Tom Dyas.
7 * Added hooks for /proc/sys/net (minor, minor patch), 96/4/1, Mike Shaver.
8 * Added kernel/java-{interpreter,appletviewer}, 96/5/10, Mike Shaver.
9 * Dynamic registration fixes, Stephen Tweedie.
10 * Added kswapd-interval, ctrl-alt-del, printk stuff, 1/8/97, Chris Horn.
11 * Made sysctl support optional via CONFIG_SYSCTL, 1/10/97, Chris
13 * Added proc_doulongvec_ms_jiffies_minmax, 09/08/99, Carlos H. Bauer.
14 * Added proc_doulongvec_minmax, 09/08/99, Carlos H. Bauer.
15 * Changed linked lists to use list.h instead of lists.h, 02/24/00, Bill
17 * The list_for_each() macro wasn't appropriate for the sysctl loop.
18 * Removed it and replaced it with older style, 03/23/00, Bill Wendling
21 #include <linux/config.h>
23 #include <linux/swap.h>
24 #include <linux/slab.h>
25 #include <linux/sysctl.h>
26 #include <linux/proc_fs.h>
27 #include <linux/ctype.h>
28 #include <linux/utsname.h>
29 #include <linux/capability.h>
30 #include <linux/smp_lock.h>
31 #include <linux/init.h>
32 #include <linux/kernel.h>
33 #include <linux/sysrq.h>
34 #include <linux/highuid.h>
35 #include <linux/writeback.h>
36 #include <linux/hugetlb.h>
37 #include <linux/security.h>
38 #include <asm/uaccess.h>
40 #ifdef CONFIG_ROOT_NFS
41 #include <linux/nfs_fs.h>
44 #if defined(CONFIG_SYSCTL)
46 /* External variables not in a header file. */
47 extern int panic_timeout
;
49 extern int sysctl_overcommit_memory
;
50 extern int sysctl_overcommit_ratio
;
51 extern int max_threads
;
52 extern atomic_t nr_queued_signals
;
53 extern int max_queued_signals
;
54 extern int sysrq_enabled
;
55 extern int core_uses_pid
;
56 extern char core_pattern
[];
59 extern int sysctl_lower_zone_protection
;
61 /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
62 static int maxolduid
= 65535;
66 extern char modprobe_path
[];
69 extern char hotplug_path
[];
71 #ifdef CONFIG_CHR_DEV_SG
72 extern int sg_big_buff
;
75 extern size_t shm_ctlmax
;
76 extern size_t shm_ctlall
;
77 extern int shm_ctlmni
;
78 extern int msg_ctlmax
;
79 extern int msg_ctlmnb
;
80 extern int msg_ctlmni
;
81 extern int sem_ctls
[];
85 extern char reboot_command
[];
86 extern int stop_a_enabled
;
89 #ifdef CONFIG_ARCH_S390
91 extern int sysctl_ieee_emulation_warnings
;
93 extern int sysctl_userprocess_debug
;
96 #if defined(CONFIG_PPC32) && defined(CONFIG_6xx)
97 extern unsigned long powersave_nap
;
98 int proc_dol2crvec(ctl_table
*table
, int write
, struct file
*filp
,
99 void *buffer
, size_t *lenp
);
102 #ifdef CONFIG_BSD_PROCESS_ACCT
103 extern int acct_parm
[];
106 static int parse_table(int *, int, void *, size_t *, void *, size_t,
107 ctl_table
*, void **);
108 static int proc_doutsstring(ctl_table
*table
, int write
, struct file
*filp
,
109 void *buffer
, size_t *lenp
);
111 static ctl_table root_table
[];
112 static struct ctl_table_header root_table_header
=
113 { root_table
, LIST_HEAD_INIT(root_table_header
.ctl_entry
) };
115 static ctl_table kern_table
[];
116 static ctl_table vm_table
[];
118 extern ctl_table net_table
[];
120 static ctl_table proc_table
[];
121 static ctl_table fs_table
[];
122 static ctl_table debug_table
[];
123 static ctl_table dev_table
[];
124 extern ctl_table random_table
[];
126 /* /proc declarations: */
128 #ifdef CONFIG_PROC_FS
130 static ssize_t
proc_readsys(struct file
*, char *, size_t, loff_t
*);
131 static ssize_t
proc_writesys(struct file
*, const char *, size_t, loff_t
*);
132 static int proc_sys_permission(struct inode
*, int);
134 struct file_operations proc_sys_file_operations
= {
135 .read
= proc_readsys
,
136 .write
= proc_writesys
,
139 static struct inode_operations proc_sys_inode_operations
= {
140 .permission
= proc_sys_permission
,
143 extern struct proc_dir_entry
*proc_sys_root
;
145 static void register_proc_table(ctl_table
*, struct proc_dir_entry
*);
146 static void unregister_proc_table(ctl_table
*, struct proc_dir_entry
*);
149 /* The default sysctl tables: */
151 static ctl_table root_table
[] = {
152 {CTL_KERN
, "kernel", NULL
, 0, 0555, kern_table
},
153 {CTL_VM
, "vm", NULL
, 0, 0555, vm_table
},
155 {CTL_NET
, "net", NULL
, 0, 0555, net_table
},
157 {CTL_PROC
, "proc", NULL
, 0, 0555, proc_table
},
158 {CTL_FS
, "fs", NULL
, 0, 0555, fs_table
},
159 {CTL_DEBUG
, "debug", NULL
, 0, 0555, debug_table
},
160 {CTL_DEV
, "dev", NULL
, 0, 0555, dev_table
},
164 static ctl_table kern_table
[] = {
165 {KERN_OSTYPE
, "ostype", system_utsname
.sysname
, 64,
166 0444, NULL
, &proc_doutsstring
, &sysctl_string
},
167 {KERN_OSRELEASE
, "osrelease", system_utsname
.release
, 64,
168 0444, NULL
, &proc_doutsstring
, &sysctl_string
},
169 {KERN_VERSION
, "version", system_utsname
.version
, 64,
170 0444, NULL
, &proc_doutsstring
, &sysctl_string
},
171 {KERN_NODENAME
, "hostname", system_utsname
.nodename
, 64,
172 0644, NULL
, &proc_doutsstring
, &sysctl_string
},
173 {KERN_DOMAINNAME
, "domainname", system_utsname
.domainname
, 64,
174 0644, NULL
, &proc_doutsstring
, &sysctl_string
},
175 {KERN_PANIC
, "panic", &panic_timeout
, sizeof(int),
176 0644, NULL
, &proc_dointvec
},
177 {KERN_CORE_USES_PID
, "core_uses_pid", &core_uses_pid
, sizeof(int),
178 0644, NULL
, &proc_dointvec
},
179 {KERN_CORE_PATTERN
, "core_pattern", core_pattern
, 64,
180 0644, NULL
, &proc_dostring
, &sysctl_string
},
181 {KERN_TAINTED
, "tainted", &tainted
, sizeof(int),
182 0644, NULL
, &proc_dointvec
},
183 {KERN_CAP_BSET
, "cap-bound", &cap_bset
, sizeof(kernel_cap_t
),
184 0600, NULL
, &proc_dointvec_bset
},
185 #ifdef CONFIG_BLK_DEV_INITRD
186 {KERN_REALROOTDEV
, "real-root-dev", &real_root_dev
, sizeof(int),
187 0644, NULL
, &proc_dointvec
},
190 {KERN_SPARC_REBOOT
, "reboot-cmd", reboot_command
,
191 256, 0644, NULL
, &proc_dostring
, &sysctl_string
},
192 {KERN_SPARC_STOP_A
, "stop-a", &stop_a_enabled
, sizeof (int),
193 0644, NULL
, &proc_dointvec
},
195 #if defined(CONFIG_PPC32) && defined(CONFIG_6xx)
196 {KERN_PPC_POWERSAVE_NAP
, "powersave-nap", &powersave_nap
, sizeof(int),
197 0644, NULL
, &proc_dointvec
},
198 {KERN_PPC_L2CR
, "l2cr", NULL
, 0,
199 0644, NULL
, &proc_dol2crvec
},
201 {KERN_CTLALTDEL
, "ctrl-alt-del", &C_A_D
, sizeof(int),
202 0644, NULL
, &proc_dointvec
},
203 {KERN_PRINTK
, "printk", &console_loglevel
, 4*sizeof(int),
204 0644, NULL
, &proc_dointvec
},
206 {KERN_MODPROBE
, "modprobe", &modprobe_path
, 256,
207 0644, NULL
, &proc_dostring
, &sysctl_string
},
209 #ifdef CONFIG_HOTPLUG
210 {KERN_HOTPLUG
, "hotplug", &hotplug_path
, 256,
211 0644, NULL
, &proc_dostring
, &sysctl_string
},
213 #ifdef CONFIG_CHR_DEV_SG
214 {KERN_SG_BIG_BUFF
, "sg-big-buff", &sg_big_buff
, sizeof (int),
215 0444, NULL
, &proc_dointvec
},
217 #ifdef CONFIG_BSD_PROCESS_ACCT
218 {KERN_ACCT
, "acct", &acct_parm
, 3*sizeof(int),
219 0644, NULL
, &proc_dointvec
},
221 {KERN_RTSIGNR
, "rtsig-nr", &nr_queued_signals
, sizeof(int),
222 0444, NULL
, &proc_dointvec
},
223 {KERN_RTSIGMAX
, "rtsig-max", &max_queued_signals
, sizeof(int),
224 0644, NULL
, &proc_dointvec
},
225 #ifdef CONFIG_SYSVIPC
226 {KERN_SHMMAX
, "shmmax", &shm_ctlmax
, sizeof (size_t),
227 0644, NULL
, &proc_doulongvec_minmax
},
228 {KERN_SHMALL
, "shmall", &shm_ctlall
, sizeof (size_t),
229 0644, NULL
, &proc_doulongvec_minmax
},
230 {KERN_SHMMNI
, "shmmni", &shm_ctlmni
, sizeof (int),
231 0644, NULL
, &proc_dointvec
},
232 {KERN_MSGMAX
, "msgmax", &msg_ctlmax
, sizeof (int),
233 0644, NULL
, &proc_dointvec
},
234 {KERN_MSGMNI
, "msgmni", &msg_ctlmni
, sizeof (int),
235 0644, NULL
, &proc_dointvec
},
236 {KERN_MSGMNB
, "msgmnb", &msg_ctlmnb
, sizeof (int),
237 0644, NULL
, &proc_dointvec
},
238 {KERN_SEM
, "sem", &sem_ctls
, 4*sizeof (int),
239 0644, NULL
, &proc_dointvec
},
241 #ifdef CONFIG_MAGIC_SYSRQ
242 {KERN_SYSRQ
, "sysrq", &sysrq_enabled
, sizeof (int),
243 0644, NULL
, &proc_dointvec
},
245 {KERN_CADPID
, "cad_pid", &cad_pid
, sizeof (int),
246 0600, NULL
, &proc_dointvec
},
247 {KERN_MAX_THREADS
, "threads-max", &max_threads
, sizeof(int),
248 0644, NULL
, &proc_dointvec
},
249 {KERN_RANDOM
, "random", NULL
, 0, 0555, random_table
},
250 {KERN_OVERFLOWUID
, "overflowuid", &overflowuid
, sizeof(int), 0644, NULL
,
251 &proc_dointvec_minmax
, &sysctl_intvec
, NULL
,
252 &minolduid
, &maxolduid
},
253 {KERN_OVERFLOWGID
, "overflowgid", &overflowgid
, sizeof(int), 0644, NULL
,
254 &proc_dointvec_minmax
, &sysctl_intvec
, NULL
,
255 &minolduid
, &maxolduid
},
256 #ifdef CONFIG_ARCH_S390
257 #ifdef CONFIG_MATHEMU
258 {KERN_IEEE_EMULATION_WARNINGS
,"ieee_emulation_warnings",
259 &sysctl_ieee_emulation_warnings
,sizeof(int),0644,NULL
,&proc_dointvec
},
261 {KERN_S390_USER_DEBUG_LOGGING
,"userprocess_debug",
262 &sysctl_userprocess_debug
,sizeof(int),0644,NULL
,&proc_dointvec
},
264 {KERN_PIDMAX
, "pid_max", &pid_max
, sizeof (int),
265 0600, NULL
, &proc_dointvec
},
269 /* Constants for minimum and maximum testing in vm_table.
270 We use these as one-element integer vectors. */
273 static int one_hundred
= 100;
276 static ctl_table vm_table
[] = {
277 {VM_OVERCOMMIT_MEMORY
, "overcommit_memory", &sysctl_overcommit_memory
,
278 sizeof(sysctl_overcommit_memory
), 0644, NULL
, &proc_dointvec
},
279 {VM_OVERCOMMIT_RATIO
, "overcommit_ratio",
280 &sysctl_overcommit_ratio
, sizeof(sysctl_overcommit_ratio
), 0644,
281 NULL
, &proc_dointvec
},
282 {VM_PAGE_CLUSTER
, "page-cluster",
283 &page_cluster
, sizeof(int), 0644, NULL
, &proc_dointvec
},
284 {VM_DIRTY_BACKGROUND
, "dirty_background_ratio",
285 &dirty_background_ratio
, sizeof(dirty_background_ratio
),
286 0644, NULL
, &proc_dointvec_minmax
, &sysctl_intvec
, NULL
,
287 &zero
, &one_hundred
},
288 {VM_DIRTY_RATIO
, "dirty_ratio", &vm_dirty_ratio
,
289 sizeof(vm_dirty_ratio
), 0644, NULL
, &proc_dointvec_minmax
,
290 &sysctl_intvec
, NULL
, &zero
, &one_hundred
},
291 {VM_DIRTY_WB_CS
, "dirty_writeback_centisecs",
292 &dirty_writeback_centisecs
, sizeof(dirty_writeback_centisecs
), 0644,
293 NULL
, &proc_dointvec_minmax
, &sysctl_intvec
, NULL
,
294 /* Here, we define the range of possible values for
295 dirty_writeback_centisecs.
297 The default value is 5 seconds (500 centisec). We will use 1
298 centisec, the smallest possible value that could make any sort of
299 sense. If we allowed the user to set the interval to 0 seconds
300 (which would presumably mean to chew up all of the CPU looking for
301 dirty pages and writing them out, without taking a break), the
302 interval would effectively become 1 second (100 centisecs), due to
303 some nicely documented throttling code in wb_kupdate().
305 There is no maximum legal value for dirty_writeback. */
307 {VM_DIRTY_EXPIRE_CS
, "dirty_expire_centisecs",
308 &dirty_expire_centisecs
, sizeof(dirty_expire_centisecs
), 0644,
309 NULL
, &proc_dointvec
},
310 { VM_NR_PDFLUSH_THREADS
, "nr_pdflush_threads",
311 &nr_pdflush_threads
, sizeof nr_pdflush_threads
,
312 0444 /* read-only*/, NULL
, &proc_dointvec
},
313 {VM_SWAPPINESS
, "swappiness", &vm_swappiness
, sizeof(vm_swappiness
),
314 0644, NULL
, &proc_dointvec_minmax
, &sysctl_intvec
, NULL
, &zero
,
316 #ifdef CONFIG_HUGETLB_PAGE
317 {VM_HUGETLB_PAGES
, "nr_hugepages", &htlbpage_max
, sizeof(int), 0644,
318 NULL
, &hugetlb_sysctl_handler
},
320 {VM_LOWER_ZONE_PROTECTION
, "lower_zone_protection",
321 &sysctl_lower_zone_protection
, sizeof(sysctl_lower_zone_protection
),
322 0644, NULL
, &proc_dointvec_minmax
, &sysctl_intvec
, NULL
, &zero
,
327 static ctl_table proc_table
[] = {
331 static ctl_table fs_table
[] = {
332 {FS_NRINODE
, "inode-nr", &inodes_stat
, 2*sizeof(int),
333 0444, NULL
, &proc_dointvec
},
334 {FS_STATINODE
, "inode-state", &inodes_stat
, 7*sizeof(int),
335 0444, NULL
, &proc_dointvec
},
336 {FS_NRFILE
, "file-nr", &files_stat
, 3*sizeof(int),
337 0444, NULL
, &proc_dointvec
},
338 {FS_MAXFILE
, "file-max", &files_stat
.max_files
, sizeof(int),
339 0644, NULL
, &proc_dointvec
},
340 {FS_DENTRY
, "dentry-state", &dentry_stat
, 6*sizeof(int),
341 0444, NULL
, &proc_dointvec
},
342 {FS_OVERFLOWUID
, "overflowuid", &fs_overflowuid
, sizeof(int), 0644, NULL
,
343 &proc_dointvec_minmax
, &sysctl_intvec
, NULL
,
344 &minolduid
, &maxolduid
},
345 {FS_OVERFLOWGID
, "overflowgid", &fs_overflowgid
, sizeof(int), 0644, NULL
,
346 &proc_dointvec_minmax
, &sysctl_intvec
, NULL
,
347 &minolduid
, &maxolduid
},
348 {FS_LEASES
, "leases-enable", &leases_enable
, sizeof(int),
349 0644, NULL
, &proc_dointvec
},
350 {FS_DIR_NOTIFY
, "dir-notify-enable", &dir_notify_enable
,
351 sizeof(int), 0644, NULL
, &proc_dointvec
},
352 {FS_LEASE_TIME
, "lease-break-time", &lease_break_time
, sizeof(int),
353 0644, NULL
, &proc_dointvec
},
357 static ctl_table debug_table
[] = {
361 static ctl_table dev_table
[] = {
365 extern void init_irq_proc (void);
367 void __init
sysctl_init(void)
369 #ifdef CONFIG_PROC_FS
370 register_proc_table(root_table
, proc_sys_root
);
375 int do_sysctl(int *name
, int nlen
, void *oldval
, size_t *oldlenp
,
376 void *newval
, size_t newlen
)
378 struct list_head
*tmp
;
380 if (nlen
<= 0 || nlen
>= CTL_MAXNAME
)
384 if (!oldlenp
|| get_user(old_len
, oldlenp
))
387 tmp
= &root_table_header
.ctl_entry
;
389 struct ctl_table_header
*head
=
390 list_entry(tmp
, struct ctl_table_header
, ctl_entry
);
391 void *context
= NULL
;
392 int error
= parse_table(name
, nlen
, oldval
, oldlenp
,
393 newval
, newlen
, head
->ctl_table
,
397 if (error
!= -ENOTDIR
)
400 } while (tmp
!= &root_table_header
.ctl_entry
);
404 extern asmlinkage
long sys_sysctl(struct __sysctl_args
*args
)
406 struct __sysctl_args tmp
;
409 if (copy_from_user(&tmp
, args
, sizeof(tmp
)))
413 error
= do_sysctl(tmp
.name
, tmp
.nlen
, tmp
.oldval
, tmp
.oldlenp
,
414 tmp
.newval
, tmp
.newlen
);
420 * ctl_perm does NOT grant the superuser all rights automatically, because
421 * some sysctl variables are readonly even to root.
424 static int test_perm(int mode
, int op
)
428 else if (in_egroup_p(0))
430 if ((mode
& op
& 0007) == op
)
435 static inline int ctl_perm(ctl_table
*table
, int op
)
438 error
= security_sysctl(table
, op
);
441 return test_perm(table
->mode
, op
);
444 static int parse_table(int *name
, int nlen
,
445 void *oldval
, size_t *oldlenp
,
446 void *newval
, size_t newlen
,
447 ctl_table
*table
, void **context
)
453 if (get_user(n
, name
))
455 for ( ; table
->ctl_name
; table
++) {
456 if (n
== table
->ctl_name
|| table
->ctl_name
== CTL_ANY
) {
459 if (ctl_perm(table
, 001))
461 if (table
->strategy
) {
462 error
= table
->strategy(
465 newval
, newlen
, context
);
471 table
= table
->child
;
474 error
= do_sysctl_strategy(table
, name
, nlen
,
476 newval
, newlen
, context
);
483 /* Perform the actual read/write of a sysctl table entry. */
484 int do_sysctl_strategy (ctl_table
*table
,
486 void *oldval
, size_t *oldlenp
,
487 void *newval
, size_t newlen
, void **context
)
496 if (ctl_perm(table
, op
))
499 if (table
->strategy
) {
500 rc
= table
->strategy(table
, name
, nlen
, oldval
, oldlenp
,
501 newval
, newlen
, context
);
508 /* If there is no strategy routine, or if the strategy returns
509 * zero, proceed with automatic r/w */
510 if (table
->data
&& table
->maxlen
) {
511 if (oldval
&& oldlenp
) {
512 get_user(len
, oldlenp
);
514 if (len
> table
->maxlen
)
516 if(copy_to_user(oldval
, table
->data
, len
))
518 if(put_user(len
, oldlenp
))
522 if (newval
&& newlen
) {
524 if (len
> table
->maxlen
)
526 if(copy_from_user(table
->data
, newval
, len
))
534 * register_sysctl_table - register a sysctl hierarchy
535 * @table: the top-level table structure
536 * @insert_at_head: whether the entry should be inserted in front or at the end
538 * Register a sysctl table hierarchy. @table should be a filled in ctl_table
539 * array. An entry with a ctl_name of 0 terminates the table.
541 * The members of the &ctl_table structure are used as follows:
543 * ctl_name - This is the numeric sysctl value used by sysctl(2). The number
544 * must be unique within that level of sysctl
546 * procname - the name of the sysctl file under /proc/sys. Set to %NULL to not
547 * enter a sysctl file
549 * data - a pointer to data for use by proc_handler
551 * maxlen - the maximum size in bytes of the data
553 * mode - the file permissions for the /proc/sys file, and for sysctl(2)
555 * child - a pointer to the child sysctl table if this entry is a directory, or
558 * proc_handler - the text handler routine (described below)
560 * strategy - the strategy routine (described below)
562 * de - for internal use by the sysctl routines
564 * extra1, extra2 - extra pointers usable by the proc handler routines
566 * Leaf nodes in the sysctl tree will be represented by a single file
567 * under /proc; non-leaf nodes will be represented by directories.
569 * sysctl(2) can automatically manage read and write requests through
570 * the sysctl table. The data and maxlen fields of the ctl_table
571 * struct enable minimal validation of the values being written to be
572 * performed, and the mode field allows minimal authentication.
574 * More sophisticated management can be enabled by the provision of a
575 * strategy routine with the table entry. This will be called before
576 * any automatic read or write of the data is performed.
578 * The strategy routine may return
580 * < 0 - Error occurred (error is passed to user process)
582 * 0 - OK - proceed with automatic read or write.
584 * > 0 - OK - read or write has been done by the strategy routine, so
585 * return immediately.
587 * There must be a proc_handler routine for any terminal nodes
588 * mirrored under /proc/sys (non-terminals are handled by a built-in
589 * directory handler). Several default handlers are available to
590 * cover common cases -
592 * proc_dostring(), proc_dointvec(), proc_dointvec_jiffies(),
593 * proc_dointvec_minmax(), proc_doulongvec_ms_jiffies_minmax(),
594 * proc_doulongvec_minmax()
596 * It is the handler's job to read the input buffer from user memory
597 * and process it. The handler should return 0 on success.
599 * This routine returns %NULL on a failure to register, and a pointer
600 * to the table header on success.
602 struct ctl_table_header
*register_sysctl_table(ctl_table
* table
,
605 struct ctl_table_header
*tmp
;
606 tmp
= kmalloc(sizeof(struct ctl_table_header
), GFP_KERNEL
);
609 tmp
->ctl_table
= table
;
610 INIT_LIST_HEAD(&tmp
->ctl_entry
);
612 list_add(&tmp
->ctl_entry
, &root_table_header
.ctl_entry
);
614 list_add_tail(&tmp
->ctl_entry
, &root_table_header
.ctl_entry
);
615 #ifdef CONFIG_PROC_FS
616 register_proc_table(table
, proc_sys_root
);
622 * unregister_sysctl_table - unregister a sysctl table hierarchy
623 * @header: the header returned from register_sysctl_table
625 * Unregisters the sysctl table and all children. proc entries may not
626 * actually be removed until they are no longer used by anyone.
628 void unregister_sysctl_table(struct ctl_table_header
* header
)
630 list_del(&header
->ctl_entry
);
631 #ifdef CONFIG_PROC_FS
632 unregister_proc_table(header
->ctl_table
, proc_sys_root
);
641 #ifdef CONFIG_PROC_FS
643 /* Scan the sysctl entries in table and add them all into /proc */
644 static void register_proc_table(ctl_table
* table
, struct proc_dir_entry
*root
)
646 struct proc_dir_entry
*de
;
650 for (; table
->ctl_name
; table
++) {
651 /* Can't do anything without a proc name. */
652 if (!table
->procname
)
654 /* Maybe we can't do anything with it... */
655 if (!table
->proc_handler
&& !table
->child
) {
656 printk(KERN_WARNING
"SYSCTL: Can't register %s\n",
661 len
= strlen(table
->procname
);
665 if (table
->proc_handler
)
669 for (de
= root
->subdir
; de
; de
= de
->next
) {
670 if (proc_match(len
, table
->procname
, de
))
673 /* If the subdir exists already, de is non-NULL */
677 de
= create_proc_entry(table
->procname
, mode
, root
);
680 de
->data
= (void *) table
;
681 if (table
->proc_handler
) {
682 de
->proc_fops
= &proc_sys_file_operations
;
683 de
->proc_iops
= &proc_sys_inode_operations
;
687 if (de
->mode
& S_IFDIR
)
688 register_proc_table(table
->child
, de
);
693 * Unregister a /proc sysctl table and any subdirectories.
695 static void unregister_proc_table(ctl_table
* table
, struct proc_dir_entry
*root
)
697 struct proc_dir_entry
*de
;
698 for (; table
->ctl_name
; table
++) {
699 if (!(de
= table
->de
))
701 if (de
->mode
& S_IFDIR
) {
703 printk (KERN_ALERT
"Help - malformed sysctl tree on free\n");
706 unregister_proc_table(table
->child
, de
);
708 /* Don't unregister directories which still have entries.. */
713 /* Don't unregister proc entries that are still being used.. */
714 if (atomic_read(&de
->count
))
718 remove_proc_entry(table
->procname
, root
);
722 static ssize_t
do_rw_proc(int write
, struct file
* file
, char * buf
,
723 size_t count
, loff_t
*ppos
)
726 struct proc_dir_entry
*de
;
727 struct ctl_table
*table
;
731 de
= PDE(file
->f_dentry
->d_inode
);
732 if (!de
|| !de
->data
)
734 table
= (struct ctl_table
*) de
->data
;
735 if (!table
|| !table
->proc_handler
)
737 op
= (write
? 002 : 004);
738 if (ctl_perm(table
, op
))
744 * FIXME: we need to pass on ppos to the handler.
747 error
= (*table
->proc_handler
) (table
, write
, file
, buf
, &res
);
753 static ssize_t
proc_readsys(struct file
* file
, char * buf
,
754 size_t count
, loff_t
*ppos
)
756 return do_rw_proc(0, file
, buf
, count
, ppos
);
759 static ssize_t
proc_writesys(struct file
* file
, const char * buf
,
760 size_t count
, loff_t
*ppos
)
762 return do_rw_proc(1, file
, (char *) buf
, count
, ppos
);
765 static int proc_sys_permission(struct inode
*inode
, int op
)
767 return test_perm(inode
->i_mode
, op
);
771 * proc_dostring - read a string sysctl
772 * @table: the sysctl table
773 * @write: %TRUE if this is a write to the sysctl file
774 * @filp: the file structure
775 * @buffer: the user buffer
776 * @lenp: the size of the user buffer
778 * Reads/writes a string from/to the user buffer. If the kernel
779 * buffer provided is not large enough to hold the string, the
780 * string is truncated. The copied string is %NULL-terminated.
781 * If the string is being read by the user process, it is copied
782 * and a newline '\n' is added. It is truncated if the buffer is
785 * Returns 0 on success.
787 int proc_dostring(ctl_table
*table
, int write
, struct file
*filp
,
788 void *buffer
, size_t *lenp
)
793 if (!table
->data
|| !table
->maxlen
|| !*lenp
||
794 (filp
->f_pos
&& !write
)) {
802 while (len
< *lenp
) {
805 if (c
== 0 || c
== '\n')
809 if (len
>= table
->maxlen
)
810 len
= table
->maxlen
-1;
811 if(copy_from_user(table
->data
, buffer
, len
))
813 ((char *) table
->data
)[len
] = 0;
814 filp
->f_pos
+= *lenp
;
816 len
= strlen(table
->data
);
817 if (len
> table
->maxlen
)
822 if(copy_to_user(buffer
, table
->data
, len
))
825 if(put_user('\n', ((char *) buffer
) + len
))
836 * Special case of dostring for the UTS structure. This has locks
837 * to observe. Should this be in kernel/sys.c ????
840 static int proc_doutsstring(ctl_table
*table
, int write
, struct file
*filp
,
841 void *buffer
, size_t *lenp
)
847 r
=proc_dostring(table
,0,filp
,buffer
,lenp
);
850 down_write(&uts_sem
);
851 r
=proc_dostring(table
,1,filp
,buffer
,lenp
);
863 static int do_proc_dointvec(ctl_table
*table
, int write
, struct file
*filp
,
864 void *buffer
, size_t *lenp
, int conv
, int op
)
866 int *i
, vleft
, first
=1, neg
, val
;
870 char buf
[TMPBUFLEN
], *p
;
872 if (!table
->data
|| !table
->maxlen
|| !*lenp
||
873 (filp
->f_pos
&& !write
)) {
878 i
= (int *) table
->data
;
879 vleft
= table
->maxlen
/ sizeof(int);
882 for (; left
&& vleft
--; i
++, first
=0) {
886 if(get_user(c
,(char *) buffer
))
897 if (len
> TMPBUFLEN
-1)
899 if(copy_from_user(buf
, buffer
, len
))
903 if (*p
== '-' && left
> 1) {
907 if (*p
< '0' || *p
> '9')
909 val
= simple_strtoul(p
, &p
, 0) * conv
;
911 if ((len
< left
) && *p
&& !isspace(*p
))
918 case OP_SET
: *i
= val
; break;
919 case OP_AND
: *i
&= val
; break;
920 case OP_OR
: *i
|= val
; break;
921 case OP_MAX
: if(*i
< val
)
924 case OP_MIN
: if(*i
> val
)
932 sprintf(p
, "%d", (*i
) / conv
);
936 if(copy_to_user(buffer
, buf
, len
))
943 if (!write
&& !first
&& left
) {
944 if(put_user('\n', (char *) buffer
))
962 filp
->f_pos
+= *lenp
;
967 * proc_dointvec - read a vector of integers
968 * @table: the sysctl table
969 * @write: %TRUE if this is a write to the sysctl file
970 * @filp: the file structure
971 * @buffer: the user buffer
972 * @lenp: the size of the user buffer
974 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
975 * values from/to the user buffer, treated as an ASCII string.
977 * Returns 0 on success.
979 int proc_dointvec(ctl_table
*table
, int write
, struct file
*filp
,
980 void *buffer
, size_t *lenp
)
982 return do_proc_dointvec(table
,write
,filp
,buffer
,lenp
,1,OP_SET
);
986 * init may raise the set.
989 int proc_dointvec_bset(ctl_table
*table
, int write
, struct file
*filp
,
990 void *buffer
, size_t *lenp
)
992 if (!capable(CAP_SYS_MODULE
)) {
995 return do_proc_dointvec(table
,write
,filp
,buffer
,lenp
,1,
996 (current
->pid
== 1) ? OP_SET
: OP_AND
);
1000 * proc_dointvec_minmax - read a vector of integers with min/max values
1001 * @table: the sysctl table
1002 * @write: %TRUE if this is a write to the sysctl file
1003 * @filp: the file structure
1004 * @buffer: the user buffer
1005 * @lenp: the size of the user buffer
1007 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
1008 * values from/to the user buffer, treated as an ASCII string.
1010 * This routine will ensure the values are within the range specified by
1011 * table->extra1 (min) and table->extra2 (max).
1013 * Returns 0 on success.
1015 int proc_dointvec_minmax(ctl_table
*table
, int write
, struct file
*filp
,
1016 void *buffer
, size_t *lenp
)
1018 int *i
, *min
, *max
, vleft
, first
=1, neg
, val
;
1020 #define TMPBUFLEN 20
1021 char buf
[TMPBUFLEN
], *p
;
1023 if (!table
->data
|| !table
->maxlen
|| !*lenp
||
1024 (filp
->f_pos
&& !write
)) {
1029 i
= (int *) table
->data
;
1030 min
= (int *) table
->extra1
;
1031 max
= (int *) table
->extra2
;
1032 vleft
= table
->maxlen
/ sizeof(int);
1035 for (; left
&& vleft
--; i
++, min
++, max
++, first
=0) {
1039 if(get_user(c
, (char *) buffer
))
1044 ((char *) buffer
)++;
1050 if (len
> TMPBUFLEN
-1)
1052 if(copy_from_user(buf
, buffer
, len
))
1056 if (*p
== '-' && left
> 1) {
1060 if (*p
< '0' || *p
> '9')
1062 val
= simple_strtoul(p
, &p
, 0);
1064 if ((len
< left
) && *p
&& !isspace(*p
))
1071 if ((min
&& val
< *min
) || (max
&& val
> *max
))
1078 sprintf(p
, "%d", *i
);
1082 if(copy_to_user(buffer
, buf
, len
))
1089 if (!write
&& !first
&& left
) {
1090 if(put_user('\n', (char *) buffer
))
1095 p
= (char *) buffer
;
1098 if(get_user(c
, p
++))
1108 filp
->f_pos
+= *lenp
;
1112 static int do_proc_doulongvec_minmax(ctl_table
*table
, int write
,
1114 void *buffer
, size_t *lenp
,
1115 unsigned long convmul
,
1116 unsigned long convdiv
)
1118 #define TMPBUFLEN 20
1119 unsigned long *i
, *min
, *max
, val
;
1120 int vleft
, first
=1, neg
;
1122 char buf
[TMPBUFLEN
], *p
;
1124 if (!table
->data
|| !table
->maxlen
|| !*lenp
||
1125 (filp
->f_pos
&& !write
)) {
1130 i
= (unsigned long *) table
->data
;
1131 min
= (unsigned long *) table
->extra1
;
1132 max
= (unsigned long *) table
->extra2
;
1133 vleft
= table
->maxlen
/ sizeof(unsigned long);
1136 for (; left
&& vleft
--; i
++, min
++, max
++, first
=0) {
1140 if(get_user(c
, (char *) buffer
))
1145 ((char *) buffer
)++;
1151 if (len
> TMPBUFLEN
-1)
1153 if(copy_from_user(buf
, buffer
, len
))
1157 if (*p
== '-' && left
> 1) {
1161 if (*p
< '0' || *p
> '9')
1163 val
= simple_strtoul(p
, &p
, 0) * convmul
/ convdiv
;
1165 if ((len
< left
) && *p
&& !isspace(*p
))
1174 if ((min
&& val
< *min
) || (max
&& val
> *max
))
1181 sprintf(p
, "%lu", convdiv
* (*i
) / convmul
);
1185 if(copy_to_user(buffer
, buf
, len
))
1192 if (!write
&& !first
&& left
) {
1193 if(put_user('\n', (char *) buffer
))
1198 p
= (char *) buffer
;
1201 if(get_user(c
, p
++))
1211 filp
->f_pos
+= *lenp
;
1217 * proc_doulongvec_minmax - read a vector of long integers with min/max values
1218 * @table: the sysctl table
1219 * @write: %TRUE if this is a write to the sysctl file
1220 * @filp: the file structure
1221 * @buffer: the user buffer
1222 * @lenp: the size of the user buffer
1224 * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
1225 * values from/to the user buffer, treated as an ASCII string.
1227 * This routine will ensure the values are within the range specified by
1228 * table->extra1 (min) and table->extra2 (max).
1230 * Returns 0 on success.
1232 int proc_doulongvec_minmax(ctl_table
*table
, int write
, struct file
*filp
,
1233 void *buffer
, size_t *lenp
)
1235 return do_proc_doulongvec_minmax(table
, write
, filp
, buffer
, lenp
, 1l, 1l);
1239 * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values
1240 * @table: the sysctl table
1241 * @write: %TRUE if this is a write to the sysctl file
1242 * @filp: the file structure
1243 * @buffer: the user buffer
1244 * @lenp: the size of the user buffer
1246 * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
1247 * values from/to the user buffer, treated as an ASCII string. The values
1248 * are treated as milliseconds, and converted to jiffies when they are stored.
1250 * This routine will ensure the values are within the range specified by
1251 * table->extra1 (min) and table->extra2 (max).
1253 * Returns 0 on success.
1255 int proc_doulongvec_ms_jiffies_minmax(ctl_table
*table
, int write
,
1257 void *buffer
, size_t *lenp
)
1259 return do_proc_doulongvec_minmax(table
, write
, filp
, buffer
,
1265 * proc_dointvec_jiffies - read a vector of integers as seconds
1266 * @table: the sysctl table
1267 * @write: %TRUE if this is a write to the sysctl file
1268 * @filp: the file structure
1269 * @buffer: the user buffer
1270 * @lenp: the size of the user buffer
1272 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
1273 * values from/to the user buffer, treated as an ASCII string.
1274 * The values read are assumed to be in seconds, and are converted into
1277 * Returns 0 on success.
1279 int proc_dointvec_jiffies(ctl_table
*table
, int write
, struct file
*filp
,
1280 void *buffer
, size_t *lenp
)
1282 return do_proc_dointvec(table
,write
,filp
,buffer
,lenp
,HZ
,OP_SET
);
1285 #else /* CONFIG_PROC_FS */
1287 int proc_dostring(ctl_table
*table
, int write
, struct file
*filp
,
1288 void *buffer
, size_t *lenp
)
1293 static int proc_doutsstring(ctl_table
*table
, int write
, struct file
*filp
,
1294 void *buffer
, size_t *lenp
)
1299 int proc_dointvec(ctl_table
*table
, int write
, struct file
*filp
,
1300 void *buffer
, size_t *lenp
)
1305 int proc_dointvec_bset(ctl_table
*table
, int write
, struct file
*filp
,
1306 void *buffer
, size_t *lenp
)
1311 int proc_dointvec_minmax(ctl_table
*table
, int write
, struct file
*filp
,
1312 void *buffer
, size_t *lenp
)
1317 int proc_dointvec_jiffies(ctl_table
*table
, int write
, struct file
*filp
,
1318 void *buffer
, size_t *lenp
)
1323 int proc_doulongvec_minmax(ctl_table
*table
, int write
, struct file
*filp
,
1324 void *buffer
, size_t *lenp
)
1329 int proc_doulongvec_ms_jiffies_minmax(ctl_table
*table
, int write
,
1331 void *buffer
, size_t *lenp
)
1337 #endif /* CONFIG_PROC_FS */
1341 * General sysctl support routines
1344 /* The generic string strategy routine: */
1345 int sysctl_string(ctl_table
*table
, int *name
, int nlen
,
1346 void *oldval
, size_t *oldlenp
,
1347 void *newval
, size_t newlen
, void **context
)
1351 if (!table
->data
|| !table
->maxlen
)
1354 if (oldval
&& oldlenp
) {
1355 if(get_user(len
, oldlenp
))
1358 l
= strlen(table
->data
);
1359 if (len
> l
) len
= l
;
1360 if (len
>= table
->maxlen
)
1361 len
= table
->maxlen
;
1362 if(copy_to_user(oldval
, table
->data
, len
))
1364 if(put_user(0, ((char *) oldval
) + len
))
1366 if(put_user(len
, oldlenp
))
1370 if (newval
&& newlen
) {
1372 if (len
> table
->maxlen
)
1373 len
= table
->maxlen
;
1374 if(copy_from_user(table
->data
, newval
, len
))
1376 if (len
== table
->maxlen
)
1378 ((char *) table
->data
)[len
] = 0;
1384 * This function makes sure that all of the integers in the vector
1385 * are between the minimum and maximum values given in the arrays
1386 * table->extra1 and table->extra2, respectively.
1388 int sysctl_intvec(ctl_table
*table
, int *name
, int nlen
,
1389 void *oldval
, size_t *oldlenp
,
1390 void *newval
, size_t newlen
, void **context
)
1392 int i
, *vec
, *min
, *max
;
1395 if (newval
&& newlen
) {
1396 if (newlen
% sizeof(int) != 0)
1399 if (!table
->extra1
&& !table
->extra2
)
1402 if (newlen
> table
->maxlen
)
1403 newlen
= table
->maxlen
;
1404 length
= newlen
/ sizeof(int);
1406 vec
= (int *) newval
;
1407 min
= (int *) table
->extra1
;
1408 max
= (int *) table
->extra2
;
1410 for (i
= 0; i
< length
; i
++) {
1412 get_user(value
, vec
+ i
);
1413 if (min
&& value
< min
[i
])
1415 if (max
&& value
> max
[i
])
1422 /* Strategy function to convert jiffies to seconds */
1423 int sysctl_jiffies(ctl_table
*table
, int *name
, int nlen
,
1424 void *oldval
, size_t *oldlenp
,
1425 void *newval
, size_t newlen
, void **context
)
1430 if (get_user(olen
, oldlenp
))
1432 if (olen
!=sizeof(int))
1435 if (put_user(*(int *)(table
->data
) / HZ
, (int *)oldval
) ||
1436 (oldlenp
&& put_user(sizeof(int),oldlenp
)))
1439 if (newval
&& newlen
) {
1441 if (newlen
!= sizeof(int))
1443 if (get_user(new, (int *)newval
))
1445 *(int *)(table
->data
) = new*HZ
;
1451 #else /* CONFIG_SYSCTL */
1454 extern asmlinkage
long sys_sysctl(struct __sysctl_args
*args
)
1459 int sysctl_string(ctl_table
*table
, int *name
, int nlen
,
1460 void *oldval
, size_t *oldlenp
,
1461 void *newval
, size_t newlen
, void **context
)
1466 int sysctl_intvec(ctl_table
*table
, int *name
, int nlen
,
1467 void *oldval
, size_t *oldlenp
,
1468 void *newval
, size_t newlen
, void **context
)
1473 int sysctl_jiffies(ctl_table
*table
, int *name
, int nlen
,
1474 void *oldval
, size_t *oldlenp
,
1475 void *newval
, size_t newlen
, void **context
)
1480 int proc_dostring(ctl_table
*table
, int write
, struct file
*filp
,
1481 void *buffer
, size_t *lenp
)
1486 int proc_dointvec(ctl_table
*table
, int write
, struct file
*filp
,
1487 void *buffer
, size_t *lenp
)
1492 int proc_dointvec_bset(ctl_table
*table
, int write
, struct file
*filp
,
1493 void *buffer
, size_t *lenp
)
1498 int proc_dointvec_minmax(ctl_table
*table
, int write
, struct file
*filp
,
1499 void *buffer
, size_t *lenp
)
1504 int proc_dointvec_jiffies(ctl_table
*table
, int write
, struct file
*filp
,
1505 void *buffer
, size_t *lenp
)
1510 int proc_doulongvec_minmax(ctl_table
*table
, int write
, struct file
*filp
,
1511 void *buffer
, size_t *lenp
)
1516 int proc_doulongvec_ms_jiffies_minmax(ctl_table
*table
, int write
,
1518 void *buffer
, size_t *lenp
)
1523 struct ctl_table_header
* register_sysctl_table(ctl_table
* table
,
1529 void unregister_sysctl_table(struct ctl_table_header
* table
)
1533 #endif /* CONFIG_SYSCTL */