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 Horn.
14 #include <linux/config.h>
15 #include <linux/malloc.h>
16 #include <linux/sysctl.h>
17 #include <linux/swapctl.h>
18 #include <linux/proc_fs.h>
19 #include <linux/ctype.h>
20 #include <linux/utsname.h>
21 #include <linux/swapctl.h>
22 #include <linux/smp_lock.h>
23 #include <linux/init.h>
25 #include <asm/uaccess.h>
27 #ifdef CONFIG_ROOT_NFS
28 #include <linux/nfs_fs.h>
31 #if defined(CONFIG_SYSCTL)
33 /* External variables not in a header file. */
34 extern int panic_timeout
;
35 extern int console_loglevel
, C_A_D
;
36 extern int bdf_prm
[], bdflush_min
[], bdflush_max
[];
37 extern char binfmt_java_interpreter
[], binfmt_java_appletviewer
[];
38 extern int sysctl_overcommit_memory
;
39 extern int nr_queued_signals
, max_queued_signals
;
42 extern char modprobe_path
[];
44 #ifdef CONFIG_CHR_DEV_SG
45 extern int sg_big_buff
;
52 extern char reboot_command
[];
55 extern unsigned long htab_reclaim_on
, zero_paged_on
, powersave_nap
;
56 int proc_dol2crvec(ctl_table
*table
, int write
, struct file
*filp
,
57 void *buffer
, size_t *lenp
);
60 #ifdef CONFIG_BSD_PROCESS_ACCT
61 extern int acct_parm
[];
64 extern int pgt_cache_water
[];
66 static int parse_table(int *, int, void *, size_t *, void *, size_t,
67 ctl_table
*, void **);
68 static int proc_doutsstring(ctl_table
*table
, int write
, struct file
*filp
,
69 void *buffer
, size_t *lenp
);
72 static ctl_table root_table
[];
73 static struct ctl_table_header root_table_header
=
74 {root_table
, DNODE_SINGLE(&root_table_header
)};
76 static ctl_table kern_table
[];
77 static ctl_table vm_table
[];
79 extern ctl_table net_table
[];
81 static ctl_table proc_table
[];
82 static ctl_table fs_table
[];
83 static ctl_table debug_table
[];
84 static ctl_table dev_table
[];
87 /* /proc declarations: */
91 static ssize_t
proc_readsys(struct file
*, char *, size_t, loff_t
*);
92 static ssize_t
proc_writesys(struct file
*, const char *, size_t, loff_t
*);
93 static int proc_sys_permission(struct inode
*, int);
95 struct file_operations proc_sys_file_operations
=
98 proc_readsys
, /* read */
99 proc_writesys
, /* write */
104 NULL
, /* no special open code */
105 NULL
, /* no special flush code */
106 NULL
, /* no special release code */
107 NULL
/* can't fsync */
110 struct inode_operations proc_sys_inode_operations
=
112 &proc_sys_file_operations
,
123 NULL
, /* follow_link */
125 NULL
, /* writepage */
131 extern struct proc_dir_entry proc_sys_root
;
133 static void register_proc_table(ctl_table
*, struct proc_dir_entry
*);
134 static void unregister_proc_table(ctl_table
*, struct proc_dir_entry
*);
136 extern int inodes_stat
[];
137 extern int dentry_stat
[];
139 /* The default sysctl tables: */
141 static ctl_table root_table
[] = {
142 {CTL_KERN
, "kernel", NULL
, 0, 0555, kern_table
},
143 {CTL_VM
, "vm", NULL
, 0, 0555, vm_table
},
145 {CTL_NET
, "net", NULL
, 0, 0555, net_table
},
147 {CTL_PROC
, "proc", NULL
, 0, 0555, proc_table
},
148 {CTL_FS
, "fs", NULL
, 0, 0555, fs_table
},
149 {CTL_DEBUG
, "debug", NULL
, 0, 0555, debug_table
},
150 {CTL_DEV
, "dev", NULL
, 0, 0555, dev_table
},
154 static ctl_table kern_table
[] = {
155 {KERN_OSTYPE
, "ostype", system_utsname
.sysname
, 64,
156 0444, NULL
, &proc_doutsstring
, &sysctl_string
},
157 {KERN_OSRELEASE
, "osrelease", system_utsname
.release
, 64,
158 0444, NULL
, &proc_doutsstring
, &sysctl_string
},
159 {KERN_VERSION
, "version", system_utsname
.version
, 64,
160 0444, NULL
, &proc_doutsstring
, &sysctl_string
},
161 {KERN_NODENAME
, "hostname", system_utsname
.nodename
, 64,
162 0644, NULL
, &proc_doutsstring
, &sysctl_string
},
163 {KERN_DOMAINNAME
, "domainname", system_utsname
.domainname
, 64,
164 0644, NULL
, &proc_doutsstring
, &sysctl_string
},
165 {KERN_PANIC
, "panic", &panic_timeout
, sizeof(int),
166 0644, NULL
, &proc_dointvec
},
167 #ifdef CONFIG_BLK_DEV_INITRD
168 {KERN_REALROOTDEV
, "real-root-dev", &real_root_dev
, sizeof(int),
169 0644, NULL
, &proc_dointvec
},
171 #ifdef CONFIG_BINFMT_JAVA
172 {KERN_JAVA_INTERPRETER
, "java-interpreter", binfmt_java_interpreter
,
173 64, 0644, NULL
, &proc_dostring
, &sysctl_string
},
174 {KERN_JAVA_APPLETVIEWER
, "java-appletviewer", binfmt_java_appletviewer
,
175 64, 0644, NULL
, &proc_dostring
, &sysctl_string
},
178 {KERN_SPARC_REBOOT
, "reboot-cmd", reboot_command
,
179 256, 0644, NULL
, &proc_dostring
, &sysctl_string
},
182 {KERN_PPC_HTABRECLAIM
, "htab-reclaim", &htab_reclaim_on
, sizeof(int),
183 0644, NULL
, &proc_dointvec
},
184 {KERN_PPC_ZEROPAGED
, "zero-paged", &zero_paged_on
, sizeof(int),
185 0644, NULL
, &proc_dointvec
},
186 {KERN_PPC_POWERSAVE_NAP
, "powersave-nap", &powersave_nap
, sizeof(int),
187 0644, NULL
, &proc_dointvec
},
188 {KERN_PPC_L2CR
, "l2cr", NULL
, 0,
189 0644, NULL
, &proc_dol2crvec
},
191 {KERN_CTLALTDEL
, "ctrl-alt-del", &C_A_D
, sizeof(int),
192 0644, NULL
, &proc_dointvec
},
193 {KERN_PRINTK
, "printk", &console_loglevel
, 4*sizeof(int),
194 0644, NULL
, &proc_dointvec
},
196 {KERN_MODPROBE
, "modprobe", &modprobe_path
, 256,
197 0644, NULL
, &proc_dostring
, &sysctl_string
},
199 #ifdef CONFIG_CHR_DEV_SG
200 {KERN_SG_BIG_BUFF
, "sg-big-buff", &sg_big_buff
, sizeof (int),
201 0444, NULL
, &proc_dointvec
},
203 #ifdef CONFIG_BSD_PROCESS_ACCT
204 {KERN_ACCT
, "acct", &acct_parm
, 3*sizeof(int),
205 0644, NULL
, &proc_dointvec
},
207 {KERN_RTSIGNR
, "rtsig-nr", &nr_queued_signals
, sizeof(int),
208 0444, NULL
, &proc_dointvec
},
209 {KERN_RTSIGMAX
, "rtsig-max", &max_queued_signals
, sizeof(int),
210 0644, NULL
, &proc_dointvec
},
211 #ifdef CONFIG_SYSVIPC
212 {KERN_SHMMAX
, "shmmax", &shmmax
, sizeof (int),
213 0644, NULL
, &proc_dointvec
},
218 static ctl_table vm_table
[] = {
219 {VM_FREEPG
, "freepages",
220 &freepages
, sizeof(freepages_t
), 0644, NULL
, &proc_dointvec
},
221 {VM_BDFLUSH
, "bdflush", &bdf_prm
, 9*sizeof(int), 0600, NULL
,
222 &proc_dointvec_minmax
, &sysctl_intvec
, NULL
,
223 &bdflush_min
, &bdflush_max
},
224 {VM_OVERCOMMIT_MEMORY
, "overcommit_memory", &sysctl_overcommit_memory
,
225 sizeof(sysctl_overcommit_memory
), 0644, NULL
, &proc_dointvec
},
226 {VM_BUFFERMEM
, "buffermem",
227 &buffer_mem
, sizeof(buffer_mem_t
), 0644, NULL
, &proc_dointvec
},
228 {VM_PAGECACHE
, "pagecache",
229 &page_cache
, sizeof(buffer_mem_t
), 0644, NULL
, &proc_dointvec
},
230 {VM_PAGERDAEMON
, "kswapd",
231 &pager_daemon
, sizeof(pager_daemon_t
), 0644, NULL
, &proc_dointvec
},
232 {VM_PGT_CACHE
, "pagetable_cache",
233 &pgt_cache_water
, 2*sizeof(int), 0600, NULL
, &proc_dointvec
},
234 {VM_PAGE_CLUSTER
, "page-cluster",
235 &page_cluster
, sizeof(int), 0600, NULL
, &proc_dointvec
},
239 static ctl_table proc_table
[] = {
243 static ctl_table fs_table
[] = {
244 {FS_NRINODE
, "inode-nr", &inodes_stat
, 2*sizeof(int),
245 0444, NULL
, &proc_dointvec
},
246 {FS_STATINODE
, "inode-state", &inodes_stat
, 7*sizeof(int),
247 0444, NULL
, &proc_dointvec
},
248 {FS_MAXINODE
, "inode-max", &max_inodes
, sizeof(int),
249 0644, NULL
, &proc_dointvec
},
250 {FS_NRFILE
, "file-nr", &nr_files
, 3*sizeof(int),
251 0444, NULL
, &proc_dointvec
},
252 {FS_MAXFILE
, "file-max", &max_files
, sizeof(int),
253 0644, NULL
, &proc_dointvec
},
254 {FS_NRSUPER
, "super-nr", &nr_super_blocks
, sizeof(int),
255 0444, NULL
, &proc_dointvec
},
256 {FS_MAXSUPER
, "super-max", &max_super_blocks
, sizeof(int),
257 0644, NULL
, &proc_dointvec
},
258 {FS_NRDQUOT
, "dquot-nr", &nr_dquots
, 2*sizeof(int),
259 0444, NULL
, &proc_dointvec
},
260 {FS_MAXDQUOT
, "dquot-max", &max_dquots
, sizeof(int),
261 0644, NULL
, &proc_dointvec
},
262 {FS_DENTRY
, "dentry-state", &dentry_stat
, 6*sizeof(int),
263 0444, NULL
, &proc_dointvec
},
267 static ctl_table debug_table
[] = {
271 static ctl_table dev_table
[] = {
276 void __init
sysctl_init(void)
278 #ifdef CONFIG_PROC_FS
279 register_proc_table(root_table
, &proc_sys_root
);
284 int do_sysctl (int *name
, int nlen
,
285 void *oldval
, size_t *oldlenp
,
286 void *newval
, size_t newlen
)
289 struct ctl_table_header
*tmp
;
292 if (nlen
== 0 || nlen
>= CTL_MAXNAME
)
300 if(get_user(old_len
, oldlenp
))
303 tmp
= &root_table_header
;
306 error
= parse_table(name
, nlen
, oldval
, oldlenp
,
307 newval
, newlen
, tmp
->ctl_table
, &context
);
310 if (error
!= -ENOTDIR
)
312 tmp
= tmp
->DLIST_NEXT(ctl_entry
);
313 } while (tmp
!= &root_table_header
);
317 extern asmlinkage
int sys_sysctl(struct __sysctl_args
*args
)
319 struct __sysctl_args tmp
;
322 if(copy_from_user(&tmp
, args
, sizeof(tmp
)))
326 error
= do_sysctl(tmp
.name
, tmp
.nlen
, tmp
.oldval
, tmp
.oldlenp
,
327 tmp
.newval
, tmp
.newlen
);
332 /* Like in_group_p, but testing against egid, not fsgid */
333 static int in_egroup_p(gid_t grp
)
335 if (grp
!= current
->egid
) {
336 int i
= current
->ngroups
;
338 gid_t
*groups
= current
->groups
;
352 /* ctl_perm does NOT grant the superuser all rights automatically, because
353 some sysctl variables are readonly even to root. */
355 static int test_perm(int mode
, int op
)
359 else if (in_egroup_p(0))
361 if ((mode
& op
& 0007) == op
)
366 static inline int ctl_perm(ctl_table
*table
, int op
)
368 return test_perm(table
->mode
, op
);
371 static int parse_table(int *name
, int nlen
,
372 void *oldval
, size_t *oldlenp
,
373 void *newval
, size_t newlen
,
374 ctl_table
*table
, void **context
)
381 for ( ; table
->ctl_name
; table
++) {
385 if (n
== table
->ctl_name
||
386 table
->ctl_name
== CTL_ANY
) {
388 if (ctl_perm(table
, 001))
390 if (table
->strategy
) {
391 error
= table
->strategy(
394 newval
, newlen
, context
);
400 table
= table
->child
;
403 error
= do_sysctl_strategy(table
, name
, nlen
,
405 newval
, newlen
, context
);
412 /* Perform the actual read/write of a sysctl table entry. */
413 int do_sysctl_strategy (ctl_table
*table
,
415 void *oldval
, size_t *oldlenp
,
416 void *newval
, size_t newlen
, void **context
)
424 if (ctl_perm(table
, op
))
427 if (table
->strategy
) {
428 rc
= table
->strategy(table
, name
, nlen
, oldval
, oldlenp
,
429 newval
, newlen
, context
);
436 /* If there is no strategy routine, or if the strategy returns
437 * zero, proceed with automatic r/w */
438 if (table
->data
&& table
->maxlen
) {
439 if (oldval
&& oldlenp
) {
440 get_user(len
, oldlenp
);
442 if (len
> table
->maxlen
)
444 if(copy_to_user(oldval
, table
->data
, len
))
446 if(put_user(len
, oldlenp
))
450 if (newval
&& newlen
) {
452 if (len
> table
->maxlen
)
454 if(copy_from_user(table
->data
, newval
, len
))
461 struct ctl_table_header
*register_sysctl_table(ctl_table
* table
,
464 struct ctl_table_header
*tmp
;
465 tmp
= kmalloc(sizeof(*tmp
), GFP_KERNEL
);
468 *tmp
= ((struct ctl_table_header
) {table
, DNODE_NULL
});
470 DLIST_INSERT_AFTER(&root_table_header
, tmp
, ctl_entry
);
472 DLIST_INSERT_BEFORE(&root_table_header
, tmp
, ctl_entry
);
473 #ifdef CONFIG_PROC_FS
474 register_proc_table(table
, &proc_sys_root
);
480 * Unlink and free a ctl_table.
482 void unregister_sysctl_table(struct ctl_table_header
* header
)
484 DLIST_DELETE(header
, ctl_entry
);
485 #ifdef CONFIG_PROC_FS
486 unregister_proc_table(header
->ctl_table
, &proc_sys_root
);
495 #ifdef CONFIG_PROC_FS
497 /* Scan the sysctl entries in table and add them all into /proc */
498 static void register_proc_table(ctl_table
* table
, struct proc_dir_entry
*root
)
500 struct proc_dir_entry
*de
;
504 for (; table
->ctl_name
; table
++) {
505 /* Can't do anything without a proc name. */
506 if (!table
->procname
)
508 /* Maybe we can't do anything with it... */
509 if (!table
->proc_handler
&& !table
->child
) {
510 printk(KERN_WARNING
"SYSCTL: Can't register %s\n",
515 len
= strlen(table
->procname
);
519 if (table
->proc_handler
)
523 for (de
= root
->subdir
; de
; de
= de
->next
) {
524 if (proc_match(len
, table
->procname
, de
))
527 /* If the subdir exists already, de is non-NULL */
531 de
= create_proc_entry(table
->procname
, mode
, root
);
534 de
->data
= (void *) table
;
535 if (table
->proc_handler
)
536 de
->ops
= &proc_sys_inode_operations
;
540 if (de
->mode
& S_IFDIR
)
541 register_proc_table(table
->child
, de
);
546 * Unregister a /proc sysctl table and any subdirectories.
548 static void unregister_proc_table(ctl_table
* table
, struct proc_dir_entry
*root
)
550 struct proc_dir_entry
*de
;
551 for (; table
->ctl_name
; table
++) {
552 if (!(de
= table
->de
))
554 if (de
->mode
& S_IFDIR
) {
556 printk (KERN_ALERT
"Help - malformed sysctl tree on free\n");
559 unregister_proc_table(table
->child
, de
);
561 /* Don't unregister directories which still have entries.. */
566 /* Don't unregoster proc entries that are still being used.. */
570 proc_unregister(root
, de
->low_ino
);
576 static ssize_t
do_rw_proc(int write
, struct file
* file
, char * buf
,
577 size_t count
, loff_t
*ppos
)
580 struct proc_dir_entry
*de
;
581 struct ctl_table
*table
;
585 de
= (struct proc_dir_entry
*) file
->f_dentry
->d_inode
->u
.generic_ip
;
586 if (!de
|| !de
->data
)
588 table
= (struct ctl_table
*) de
->data
;
589 if (!table
|| !table
->proc_handler
)
591 op
= (write
? 002 : 004);
592 if (ctl_perm(table
, op
))
598 * FIXME: we need to pass on ppos to the handler.
601 error
= (*table
->proc_handler
) (table
, write
, file
, buf
, &res
);
607 static ssize_t
proc_readsys(struct file
* file
, char * buf
,
608 size_t count
, loff_t
*ppos
)
610 return do_rw_proc(0, file
, buf
, count
, ppos
);
613 static ssize_t
proc_writesys(struct file
* file
, const char * buf
,
614 size_t count
, loff_t
*ppos
)
616 return do_rw_proc(1, file
, (char *) buf
, count
, ppos
);
619 static int proc_sys_permission(struct inode
*inode
, int op
)
621 return test_perm(inode
->i_mode
, op
);
624 int proc_dostring(ctl_table
*table
, int write
, struct file
*filp
,
625 void *buffer
, size_t *lenp
)
630 if (!table
->data
|| !table
->maxlen
|| !*lenp
||
631 (filp
->f_pos
&& !write
)) {
639 while (len
< *lenp
) {
642 if (c
== 0 || c
== '\n')
646 if (len
>= table
->maxlen
)
647 len
= table
->maxlen
-1;
648 if(copy_from_user(table
->data
, buffer
, len
))
650 ((char *) table
->data
)[len
] = 0;
651 filp
->f_pos
+= *lenp
;
653 len
= strlen(table
->data
);
654 if (len
> table
->maxlen
)
659 if(copy_to_user(buffer
, table
->data
, len
))
662 if(put_user('\n', ((char *) buffer
) + len
))
673 * Special case of dostring for the UTS structure. This has locks
674 * to observe. Should this be in kernel/sys.c ????
677 static int proc_doutsstring(ctl_table
*table
, int write
, struct file
*filp
,
678 void *buffer
, size_t *lenp
)
682 r
=proc_dostring(table
,write
,filp
,buffer
,lenp
);
687 static int do_proc_dointvec(ctl_table
*table
, int write
, struct file
*filp
,
688 void *buffer
, size_t *lenp
, int conv
)
690 int *i
, vleft
, first
=1, len
, left
, neg
, val
;
692 char buf
[TMPBUFLEN
], *p
;
694 if (!table
->data
|| !table
->maxlen
|| !*lenp
||
695 (filp
->f_pos
&& !write
)) {
700 i
= (int *) table
->data
;
701 vleft
= table
->maxlen
/ sizeof(int);
704 for (; left
&& vleft
--; i
++, first
=0) {
708 if(get_user(c
,(char *) buffer
))
719 if (len
> TMPBUFLEN
-1)
721 if(copy_from_user(buf
, buffer
, len
))
725 if (*p
== '-' && left
> 1) {
729 if (*p
< '0' || *p
> '9')
731 val
= simple_strtoul(p
, &p
, 0) * conv
;
733 if ((len
< left
) && *p
&& !isspace(*p
))
744 sprintf(p
, "%d", (*i
) / conv
);
748 if(copy_to_user(buffer
, buf
, len
))
755 if (!write
&& !first
&& left
) {
756 if(put_user('\n', (char *) buffer
))
774 filp
->f_pos
+= *lenp
;
778 int proc_dointvec(ctl_table
*table
, int write
, struct file
*filp
,
779 void *buffer
, size_t *lenp
)
781 return do_proc_dointvec(table
,write
,filp
,buffer
,lenp
,1);
784 int proc_dointvec_minmax(ctl_table
*table
, int write
, struct file
*filp
,
785 void *buffer
, size_t *lenp
)
787 int *i
, *min
, *max
, vleft
, first
=1, len
, left
, neg
, val
;
789 char buf
[TMPBUFLEN
], *p
;
791 if (!table
->data
|| !table
->maxlen
|| !*lenp
||
792 (filp
->f_pos
&& !write
)) {
797 i
= (int *) table
->data
;
798 min
= (int *) table
->extra1
;
799 max
= (int *) table
->extra2
;
800 vleft
= table
->maxlen
/ sizeof(int);
803 for (; left
&& vleft
--; i
++, first
=0) {
807 if(get_user(c
, (char *) buffer
))
818 if (len
> TMPBUFLEN
-1)
820 if(copy_from_user(buf
, buffer
, len
))
824 if (*p
== '-' && left
> 1) {
828 if (*p
< '0' || *p
> '9')
830 val
= simple_strtoul(p
, &p
, 0);
832 if ((len
< left
) && *p
&& !isspace(*p
))
839 if (min
&& val
< *min
++)
841 if (max
&& val
> *max
++)
848 sprintf(p
, "%d", *i
);
852 if(copy_to_user(buffer
, buf
, len
))
859 if (!write
&& !first
&& left
) {
860 if(put_user('\n', (char *) buffer
))
878 filp
->f_pos
+= *lenp
;
882 /* Like proc_dointvec, but converts seconds to jiffies */
883 int proc_dointvec_jiffies(ctl_table
*table
, int write
, struct file
*filp
,
884 void *buffer
, size_t *lenp
)
886 return do_proc_dointvec(table
,write
,filp
,buffer
,lenp
,HZ
);
889 #else /* CONFIG_PROC_FS */
891 int proc_dostring(ctl_table
*table
, int write
, struct file
*filp
,
892 void *buffer
, size_t *lenp
)
897 static int proc_doutsstring(ctl_table
*table
, int write
, struct file
*filp
,
898 void *buffer
, size_t *lenp
)
903 int proc_dointvec(ctl_table
*table
, int write
, struct file
*filp
,
904 void *buffer
, size_t *lenp
)
909 int proc_dointvec_minmax(ctl_table
*table
, int write
, struct file
*filp
,
910 void *buffer
, size_t *lenp
)
915 int proc_dointvec_jiffies(ctl_table
*table
, int write
, struct file
*filp
,
916 void *buffer
, size_t *lenp
)
921 #endif /* CONFIG_PROC_FS */
925 * General sysctl support routines
928 /* The generic string strategy routine: */
929 int sysctl_string(ctl_table
*table
, int *name
, int nlen
,
930 void *oldval
, size_t *oldlenp
,
931 void *newval
, size_t newlen
, void **context
)
935 if (!table
->data
|| !table
->maxlen
)
938 if (oldval
&& oldlenp
) {
939 if(get_user(len
, oldlenp
))
942 l
= strlen(table
->data
);
943 if (len
> l
) len
= l
;
944 if (len
>= table
->maxlen
)
946 if(copy_to_user(oldval
, table
->data
, len
))
948 if(put_user(0, ((char *) oldval
) + len
))
950 if(put_user(len
, oldlenp
))
954 if (newval
&& newlen
) {
956 if (len
> table
->maxlen
)
958 if(copy_from_user(table
->data
, newval
, len
))
960 if (len
== table
->maxlen
)
962 ((char *) table
->data
)[len
] = 0;
968 * This function makes sure that all of the integers in the vector
969 * are between the minimum and maximum values given in the arrays
970 * table->extra1 and table->extra2, respectively.
972 int sysctl_intvec(ctl_table
*table
, int *name
, int nlen
,
973 void *oldval
, size_t *oldlenp
,
974 void *newval
, size_t newlen
, void **context
)
976 int i
, length
, *vec
, *min
, *max
;
978 if (newval
&& newlen
) {
979 if (newlen
% sizeof(int) != 0)
982 if (!table
->extra1
&& !table
->extra2
)
985 if (newlen
> table
->maxlen
)
986 newlen
= table
->maxlen
;
987 length
= newlen
/ sizeof(int);
989 vec
= (int *) newval
;
990 min
= (int *) table
->extra1
;
991 max
= (int *) table
->extra2
;
993 for (i
= 0; i
< length
; i
++) {
995 get_user(value
, vec
+ i
);
996 if (min
&& value
< min
[i
])
998 if (max
&& value
> max
[i
])
1006 void *oldval
, size_t *oldlenp
, void *newval
, size_t newlen
,
1007 int rdwr
, char *data
, size_t max
)
1009 int l
= strlen(data
) + 1;
1010 if (newval
&& !rdwr
)
1012 if (newval
&& newlen
>= max
)
1016 if(get_user(old_l
, oldlenp
))
1020 if(put_user(l
, oldlenp
) || copy_to_user(oldval
, data
, l
))
1024 if(copy_from_user(data
, newval
, newlen
))
1032 void *oldval
, size_t *oldlenp
, void *newval
, size_t newlen
,
1033 int rdwr
, int *data
)
1035 if (newval
&& !rdwr
)
1037 if (newval
&& newlen
!= sizeof(int))
1041 if(get_user(old_l
, oldlenp
))
1043 if (old_l
< sizeof(int))
1045 if(put_user(sizeof(int), oldlenp
)||copy_to_user(oldval
, data
, sizeof(int)))
1049 if(copy_from_user(data
, newval
, sizeof(int)))
1055 void *oldval
, size_t *oldlenp
, void *newval
, size_t newlen
,
1056 int rdwr
, void *data
, size_t len
)
1058 if (newval
&& !rdwr
)
1060 if (newval
&& newlen
!= len
)
1064 if(get_user(old_l
, oldlenp
))
1068 if(put_user(len
, oldlenp
) || copy_to_user(oldval
, data
, len
))
1072 if(copy_from_user(data
, newval
, len
))
1078 #else /* CONFIG_SYSCTL */
1081 extern asmlinkage
int sys_sysctl(struct __sysctl_args
*args
)
1086 int sysctl_string(ctl_table
*table
, int *name
, int nlen
,
1087 void *oldval
, size_t *oldlenp
,
1088 void *newval
, size_t newlen
, void **context
)
1093 int sysctl_intvec(ctl_table
*table
, int *name
, int nlen
,
1094 void *oldval
, size_t *oldlenp
,
1095 void *newval
, size_t newlen
, void **context
)
1100 int proc_dostring(ctl_table
*table
, int write
, struct file
*filp
,
1101 void *buffer
, size_t *lenp
)
1106 int proc_dointvec(ctl_table
*table
, int write
, struct file
*filp
,
1107 void *buffer
, size_t *lenp
)
1112 int proc_dointvec_minmax(ctl_table
*table
, int write
, struct file
*filp
,
1113 void *buffer
, size_t *lenp
)
1118 int proc_dointvec_jiffies(ctl_table
*table
, int write
, struct file
*filp
,
1119 void *buffer
, size_t *lenp
)
1124 struct ctl_table_header
* register_sysctl_table(ctl_table
* table
,
1130 void unregister_sysctl_table(struct ctl_table_header
* table
)
1134 #endif /* CONFIG_SYSCTL */