aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sysctl.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2008-01-30 19:25:51 -0500
committerPaul Mackerras <paulus@samba.org>2008-01-30 19:25:51 -0500
commitbd45ac0c5daae35e7c71138172e63df5cf644cf6 (patch)
tree5eb5a599bf6a9d7a8a34e802db932aa9e9555de4 /kernel/sysctl.c
parent4eece4ccf997c0e6d8fdad3d842e37b16b8d705f (diff)
parent5bdeae46be6dfe9efa44a548bd622af325f4bdb4 (diff)
Merge branch 'linux-2.6'
Diffstat (limited to 'kernel/sysctl.c')
-rw-r--r--kernel/sysctl.c267
1 files changed, 235 insertions, 32 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c68f68dcc605..357b68ba23ec 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -53,6 +53,7 @@
53#ifdef CONFIG_X86 53#ifdef CONFIG_X86
54#include <asm/nmi.h> 54#include <asm/nmi.h>
55#include <asm/stacktrace.h> 55#include <asm/stacktrace.h>
56#include <asm/io.h>
56#endif 57#endif
57 58
58static int deprecated_sysctl_warning(struct __sysctl_args *args); 59static int deprecated_sysctl_warning(struct __sysctl_args *args);
@@ -81,6 +82,7 @@ extern int compat_log;
81extern int maps_protect; 82extern int maps_protect;
82extern int sysctl_stat_interval; 83extern int sysctl_stat_interval;
83extern int audit_argv_kb; 84extern int audit_argv_kb;
85extern int latencytop_enabled;
84 86
85/* Constants used for minimum and maximum */ 87/* Constants used for minimum and maximum */
86#ifdef CONFIG_DETECT_SOFTLOCKUP 88#ifdef CONFIG_DETECT_SOFTLOCKUP
@@ -156,8 +158,16 @@ static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *
156#endif 158#endif
157 159
158static struct ctl_table root_table[]; 160static struct ctl_table root_table[];
159static struct ctl_table_header root_table_header = 161static struct ctl_table_root sysctl_table_root;
160 { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) }; 162static struct ctl_table_header root_table_header = {
163 .ctl_table = root_table,
164 .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.header_list),
165 .root = &sysctl_table_root,
166};
167static struct ctl_table_root sysctl_table_root = {
168 .root_list = LIST_HEAD_INIT(sysctl_table_root.root_list),
169 .header_list = LIST_HEAD_INIT(root_table_header.ctl_entry),
170};
161 171
162static struct ctl_table kern_table[]; 172static struct ctl_table kern_table[];
163static struct ctl_table vm_table[]; 173static struct ctl_table vm_table[];
@@ -191,14 +201,6 @@ static struct ctl_table root_table[] = {
191 .mode = 0555, 201 .mode = 0555,
192 .child = vm_table, 202 .child = vm_table,
193 }, 203 },
194#ifdef CONFIG_NET
195 {
196 .ctl_name = CTL_NET,
197 .procname = "net",
198 .mode = 0555,
199 .child = net_table,
200 },
201#endif
202 { 204 {
203 .ctl_name = CTL_FS, 205 .ctl_name = CTL_FS,
204 .procname = "fs", 206 .procname = "fs",
@@ -306,9 +308,43 @@ static struct ctl_table kern_table[] = {
306 .procname = "sched_nr_migrate", 308 .procname = "sched_nr_migrate",
307 .data = &sysctl_sched_nr_migrate, 309 .data = &sysctl_sched_nr_migrate,
308 .maxlen = sizeof(unsigned int), 310 .maxlen = sizeof(unsigned int),
309 .mode = 644, 311 .mode = 0644,
312 .proc_handler = &proc_dointvec,
313 },
314 {
315 .ctl_name = CTL_UNNUMBERED,
316 .procname = "sched_rt_period_ms",
317 .data = &sysctl_sched_rt_period,
318 .maxlen = sizeof(unsigned int),
319 .mode = 0644,
320 .proc_handler = &proc_dointvec,
321 },
322 {
323 .ctl_name = CTL_UNNUMBERED,
324 .procname = "sched_rt_ratio",
325 .data = &sysctl_sched_rt_ratio,
326 .maxlen = sizeof(unsigned int),
327 .mode = 0644,
310 .proc_handler = &proc_dointvec, 328 .proc_handler = &proc_dointvec,
311 }, 329 },
330#if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP)
331 {
332 .ctl_name = CTL_UNNUMBERED,
333 .procname = "sched_min_bal_int_shares",
334 .data = &sysctl_sched_min_bal_int_shares,
335 .maxlen = sizeof(unsigned int),
336 .mode = 0644,
337 .proc_handler = &proc_dointvec,
338 },
339 {
340 .ctl_name = CTL_UNNUMBERED,
341 .procname = "sched_max_bal_int_shares",
342 .data = &sysctl_sched_max_bal_int_shares,
343 .maxlen = sizeof(unsigned int),
344 .mode = 0644,
345 .proc_handler = &proc_dointvec,
346 },
347#endif
312#endif 348#endif
313 { 349 {
314 .ctl_name = CTL_UNNUMBERED, 350 .ctl_name = CTL_UNNUMBERED,
@@ -382,6 +418,15 @@ static struct ctl_table kern_table[] = {
382 .proc_handler = &proc_dointvec_taint, 418 .proc_handler = &proc_dointvec_taint,
383 }, 419 },
384#endif 420#endif
421#ifdef CONFIG_LATENCYTOP
422 {
423 .procname = "latencytop",
424 .data = &latencytop_enabled,
425 .maxlen = sizeof(int),
426 .mode = 0644,
427 .proc_handler = &proc_dointvec,
428 },
429#endif
385#ifdef CONFIG_SECURITY_CAPABILITIES 430#ifdef CONFIG_SECURITY_CAPABILITIES
386 { 431 {
387 .procname = "cap-bound", 432 .procname = "cap-bound",
@@ -683,6 +728,14 @@ static struct ctl_table kern_table[] = {
683 .mode = 0644, 728 .mode = 0644,
684 .proc_handler = &proc_dointvec, 729 .proc_handler = &proc_dointvec,
685 }, 730 },
731 {
732 .ctl_name = CTL_UNNUMBERED,
733 .procname = "io_delay_type",
734 .data = &io_delay_type,
735 .maxlen = sizeof(int),
736 .mode = 0644,
737 .proc_handler = &proc_dointvec,
738 },
686#endif 739#endif
687#if defined(CONFIG_MMU) 740#if defined(CONFIG_MMU)
688 { 741 {
@@ -728,13 +781,40 @@ static struct ctl_table kern_table[] = {
728 .ctl_name = CTL_UNNUMBERED, 781 .ctl_name = CTL_UNNUMBERED,
729 .procname = "softlockup_thresh", 782 .procname = "softlockup_thresh",
730 .data = &softlockup_thresh, 783 .data = &softlockup_thresh,
731 .maxlen = sizeof(int), 784 .maxlen = sizeof(unsigned long),
732 .mode = 0644, 785 .mode = 0644,
733 .proc_handler = &proc_dointvec_minmax, 786 .proc_handler = &proc_doulongvec_minmax,
734 .strategy = &sysctl_intvec, 787 .strategy = &sysctl_intvec,
735 .extra1 = &one, 788 .extra1 = &one,
736 .extra2 = &sixty, 789 .extra2 = &sixty,
737 }, 790 },
791 {
792 .ctl_name = CTL_UNNUMBERED,
793 .procname = "hung_task_check_count",
794 .data = &sysctl_hung_task_check_count,
795 .maxlen = sizeof(unsigned long),
796 .mode = 0644,
797 .proc_handler = &proc_doulongvec_minmax,
798 .strategy = &sysctl_intvec,
799 },
800 {
801 .ctl_name = CTL_UNNUMBERED,
802 .procname = "hung_task_timeout_secs",
803 .data = &sysctl_hung_task_timeout_secs,
804 .maxlen = sizeof(unsigned long),
805 .mode = 0644,
806 .proc_handler = &proc_doulongvec_minmax,
807 .strategy = &sysctl_intvec,
808 },
809 {
810 .ctl_name = CTL_UNNUMBERED,
811 .procname = "hung_task_warnings",
812 .data = &sysctl_hung_task_warnings,
813 .maxlen = sizeof(unsigned long),
814 .mode = 0644,
815 .proc_handler = &proc_doulongvec_minmax,
816 .strategy = &sysctl_intvec,
817 },
738#endif 818#endif
739#ifdef CONFIG_COMPAT 819#ifdef CONFIG_COMPAT
740 { 820 {
@@ -1300,12 +1380,27 @@ void sysctl_head_finish(struct ctl_table_header *head)
1300 spin_unlock(&sysctl_lock); 1380 spin_unlock(&sysctl_lock);
1301} 1381}
1302 1382
1303struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev) 1383static struct list_head *
1384lookup_header_list(struct ctl_table_root *root, struct nsproxy *namespaces)
1304{ 1385{
1386 struct list_head *header_list;
1387 header_list = &root->header_list;
1388 if (root->lookup)
1389 header_list = root->lookup(root, namespaces);
1390 return header_list;
1391}
1392
1393struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces,
1394 struct ctl_table_header *prev)
1395{
1396 struct ctl_table_root *root;
1397 struct list_head *header_list;
1305 struct ctl_table_header *head; 1398 struct ctl_table_header *head;
1306 struct list_head *tmp; 1399 struct list_head *tmp;
1400
1307 spin_lock(&sysctl_lock); 1401 spin_lock(&sysctl_lock);
1308 if (prev) { 1402 if (prev) {
1403 head = prev;
1309 tmp = &prev->ctl_entry; 1404 tmp = &prev->ctl_entry;
1310 unuse_table(prev); 1405 unuse_table(prev);
1311 goto next; 1406 goto next;
@@ -1319,14 +1414,38 @@ struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev)
1319 spin_unlock(&sysctl_lock); 1414 spin_unlock(&sysctl_lock);
1320 return head; 1415 return head;
1321 next: 1416 next:
1417 root = head->root;
1322 tmp = tmp->next; 1418 tmp = tmp->next;
1323 if (tmp == &root_table_header.ctl_entry) 1419 header_list = lookup_header_list(root, namespaces);
1324 break; 1420 if (tmp != header_list)
1421 continue;
1422
1423 do {
1424 root = list_entry(root->root_list.next,
1425 struct ctl_table_root, root_list);
1426 if (root == &sysctl_table_root)
1427 goto out;
1428 header_list = lookup_header_list(root, namespaces);
1429 } while (list_empty(header_list));
1430 tmp = header_list->next;
1325 } 1431 }
1432out:
1326 spin_unlock(&sysctl_lock); 1433 spin_unlock(&sysctl_lock);
1327 return NULL; 1434 return NULL;
1328} 1435}
1329 1436
1437struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev)
1438{
1439 return __sysctl_head_next(current->nsproxy, prev);
1440}
1441
1442void register_sysctl_root(struct ctl_table_root *root)
1443{
1444 spin_lock(&sysctl_lock);
1445 list_add_tail(&root->root_list, &sysctl_table_root.root_list);
1446 spin_unlock(&sysctl_lock);
1447}
1448
1330#ifdef CONFIG_SYSCTL_SYSCALL 1449#ifdef CONFIG_SYSCTL_SYSCALL
1331int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, 1450int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp,
1332 void __user *newval, size_t newlen) 1451 void __user *newval, size_t newlen)
@@ -1483,18 +1602,21 @@ static __init int sysctl_init(void)
1483{ 1602{
1484 int err; 1603 int err;
1485 sysctl_set_parent(NULL, root_table); 1604 sysctl_set_parent(NULL, root_table);
1486 err = sysctl_check_table(root_table); 1605 err = sysctl_check_table(current->nsproxy, root_table);
1487 return 0; 1606 return 0;
1488} 1607}
1489 1608
1490core_initcall(sysctl_init); 1609core_initcall(sysctl_init);
1491 1610
1492/** 1611/**
1493 * register_sysctl_table - register a sysctl hierarchy 1612 * __register_sysctl_paths - register a sysctl hierarchy
1613 * @root: List of sysctl headers to register on
1614 * @namespaces: Data to compute which lists of sysctl entries are visible
1615 * @path: The path to the directory the sysctl table is in.
1494 * @table: the top-level table structure 1616 * @table: the top-level table structure
1495 * 1617 *
1496 * Register a sysctl table hierarchy. @table should be a filled in ctl_table 1618 * Register a sysctl table hierarchy. @table should be a filled in ctl_table
1497 * array. An entry with a ctl_name of 0 terminates the table. 1619 * array. A completely 0 filled entry terminates the table.
1498 * 1620 *
1499 * The members of the &struct ctl_table structure are used as follows: 1621 * The members of the &struct ctl_table structure are used as follows:
1500 * 1622 *
@@ -1557,25 +1679,99 @@ core_initcall(sysctl_init);
1557 * This routine returns %NULL on a failure to register, and a pointer 1679 * This routine returns %NULL on a failure to register, and a pointer
1558 * to the table header on success. 1680 * to the table header on success.
1559 */ 1681 */
1560struct ctl_table_header *register_sysctl_table(struct ctl_table * table) 1682struct ctl_table_header *__register_sysctl_paths(
1683 struct ctl_table_root *root,
1684 struct nsproxy *namespaces,
1685 const struct ctl_path *path, struct ctl_table *table)
1561{ 1686{
1562 struct ctl_table_header *tmp; 1687 struct list_head *header_list;
1563 tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL); 1688 struct ctl_table_header *header;
1564 if (!tmp) 1689 struct ctl_table *new, **prevp;
1690 unsigned int n, npath;
1691
1692 /* Count the path components */
1693 for (npath = 0; path[npath].ctl_name || path[npath].procname; ++npath)
1694 ;
1695
1696 /*
1697 * For each path component, allocate a 2-element ctl_table array.
1698 * The first array element will be filled with the sysctl entry
1699 * for this, the second will be the sentinel (ctl_name == 0).
1700 *
1701 * We allocate everything in one go so that we don't have to
1702 * worry about freeing additional memory in unregister_sysctl_table.
1703 */
1704 header = kzalloc(sizeof(struct ctl_table_header) +
1705 (2 * npath * sizeof(struct ctl_table)), GFP_KERNEL);
1706 if (!header)
1565 return NULL; 1707 return NULL;
1566 tmp->ctl_table = table; 1708
1567 INIT_LIST_HEAD(&tmp->ctl_entry); 1709 new = (struct ctl_table *) (header + 1);
1568 tmp->used = 0; 1710
1569 tmp->unregistering = NULL; 1711 /* Now connect the dots */
1570 sysctl_set_parent(NULL, table); 1712 prevp = &header->ctl_table;
1571 if (sysctl_check_table(tmp->ctl_table)) { 1713 for (n = 0; n < npath; ++n, ++path) {
1572 kfree(tmp); 1714 /* Copy the procname */
1715 new->procname = path->procname;
1716 new->ctl_name = path->ctl_name;
1717 new->mode = 0555;
1718
1719 *prevp = new;
1720 prevp = &new->child;
1721
1722 new += 2;
1723 }
1724 *prevp = table;
1725 header->ctl_table_arg = table;
1726
1727 INIT_LIST_HEAD(&header->ctl_entry);
1728 header->used = 0;
1729 header->unregistering = NULL;
1730 header->root = root;
1731 sysctl_set_parent(NULL, header->ctl_table);
1732 if (sysctl_check_table(namespaces, header->ctl_table)) {
1733 kfree(header);
1573 return NULL; 1734 return NULL;
1574 } 1735 }
1575 spin_lock(&sysctl_lock); 1736 spin_lock(&sysctl_lock);
1576 list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry); 1737 header_list = lookup_header_list(root, namespaces);
1738 list_add_tail(&header->ctl_entry, header_list);
1577 spin_unlock(&sysctl_lock); 1739 spin_unlock(&sysctl_lock);
1578 return tmp; 1740
1741 return header;
1742}
1743
1744/**
1745 * register_sysctl_table_path - register a sysctl table hierarchy
1746 * @path: The path to the directory the sysctl table is in.
1747 * @table: the top-level table structure
1748 *
1749 * Register a sysctl table hierarchy. @table should be a filled in ctl_table
1750 * array. A completely 0 filled entry terminates the table.
1751 *
1752 * See __register_sysctl_paths for more details.
1753 */
1754struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
1755 struct ctl_table *table)
1756{
1757 return __register_sysctl_paths(&sysctl_table_root, current->nsproxy,
1758 path, table);
1759}
1760
1761/**
1762 * register_sysctl_table - register a sysctl table hierarchy
1763 * @table: the top-level table structure
1764 *
1765 * Register a sysctl table hierarchy. @table should be a filled in ctl_table
1766 * array. A completely 0 filled entry terminates the table.
1767 *
1768 * See register_sysctl_paths for more details.
1769 */
1770struct ctl_table_header *register_sysctl_table(struct ctl_table *table)
1771{
1772 static const struct ctl_path null_path[] = { {} };
1773
1774 return register_sysctl_paths(null_path, table);
1579} 1775}
1580 1776
1581/** 1777/**
@@ -1604,6 +1800,12 @@ struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
1604 return NULL; 1800 return NULL;
1605} 1801}
1606 1802
1803struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
1804 struct ctl_table *table)
1805{
1806 return NULL;
1807}
1808
1607void unregister_sysctl_table(struct ctl_table_header * table) 1809void unregister_sysctl_table(struct ctl_table_header * table)
1608{ 1810{
1609} 1811}
@@ -2662,6 +2864,7 @@ EXPORT_SYMBOL(proc_dostring);
2662EXPORT_SYMBOL(proc_doulongvec_minmax); 2864EXPORT_SYMBOL(proc_doulongvec_minmax);
2663EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax); 2865EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
2664EXPORT_SYMBOL(register_sysctl_table); 2866EXPORT_SYMBOL(register_sysctl_table);
2867EXPORT_SYMBOL(register_sysctl_paths);
2665EXPORT_SYMBOL(sysctl_intvec); 2868EXPORT_SYMBOL(sysctl_intvec);
2666EXPORT_SYMBOL(sysctl_jiffies); 2869EXPORT_SYMBOL(sysctl_jiffies);
2667EXPORT_SYMBOL(sysctl_ms_jiffies); 2870EXPORT_SYMBOL(sysctl_ms_jiffies);