diff options
author | Paul Mackerras <paulus@samba.org> | 2008-01-30 19:25:51 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-01-30 19:25:51 -0500 |
commit | bd45ac0c5daae35e7c71138172e63df5cf644cf6 (patch) | |
tree | 5eb5a599bf6a9d7a8a34e802db932aa9e9555de4 /kernel/sysctl.c | |
parent | 4eece4ccf997c0e6d8fdad3d842e37b16b8d705f (diff) | |
parent | 5bdeae46be6dfe9efa44a548bd622af325f4bdb4 (diff) |
Merge branch 'linux-2.6'
Diffstat (limited to 'kernel/sysctl.c')
-rw-r--r-- | kernel/sysctl.c | 267 |
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 | ||
58 | static int deprecated_sysctl_warning(struct __sysctl_args *args); | 59 | static int deprecated_sysctl_warning(struct __sysctl_args *args); |
@@ -81,6 +82,7 @@ extern int compat_log; | |||
81 | extern int maps_protect; | 82 | extern int maps_protect; |
82 | extern int sysctl_stat_interval; | 83 | extern int sysctl_stat_interval; |
83 | extern int audit_argv_kb; | 84 | extern int audit_argv_kb; |
85 | extern 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 | ||
158 | static struct ctl_table root_table[]; | 160 | static struct ctl_table root_table[]; |
159 | static struct ctl_table_header root_table_header = | 161 | static struct ctl_table_root sysctl_table_root; |
160 | { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) }; | 162 | static 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 | }; | ||
167 | static 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 | ||
162 | static struct ctl_table kern_table[]; | 172 | static struct ctl_table kern_table[]; |
163 | static struct ctl_table vm_table[]; | 173 | static 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 | ||
1303 | struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev) | 1383 | static struct list_head * |
1384 | lookup_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 | |||
1393 | struct 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 | } |
1432 | out: | ||
1326 | spin_unlock(&sysctl_lock); | 1433 | spin_unlock(&sysctl_lock); |
1327 | return NULL; | 1434 | return NULL; |
1328 | } | 1435 | } |
1329 | 1436 | ||
1437 | struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev) | ||
1438 | { | ||
1439 | return __sysctl_head_next(current->nsproxy, prev); | ||
1440 | } | ||
1441 | |||
1442 | void 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 |
1331 | int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, | 1450 | int 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 | ||
1490 | core_initcall(sysctl_init); | 1609 | core_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 | */ |
1560 | struct ctl_table_header *register_sysctl_table(struct ctl_table * table) | 1682 | struct 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 | */ | ||
1754 | struct 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 | */ | ||
1770 | struct 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 | ||
1803 | struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path, | ||
1804 | struct ctl_table *table) | ||
1805 | { | ||
1806 | return NULL; | ||
1807 | } | ||
1808 | |||
1607 | void unregister_sysctl_table(struct ctl_table_header * table) | 1809 | void unregister_sysctl_table(struct ctl_table_header * table) |
1608 | { | 1810 | { |
1609 | } | 1811 | } |
@@ -2662,6 +2864,7 @@ EXPORT_SYMBOL(proc_dostring); | |||
2662 | EXPORT_SYMBOL(proc_doulongvec_minmax); | 2864 | EXPORT_SYMBOL(proc_doulongvec_minmax); |
2663 | EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax); | 2865 | EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax); |
2664 | EXPORT_SYMBOL(register_sysctl_table); | 2866 | EXPORT_SYMBOL(register_sysctl_table); |
2867 | EXPORT_SYMBOL(register_sysctl_paths); | ||
2665 | EXPORT_SYMBOL(sysctl_intvec); | 2868 | EXPORT_SYMBOL(sysctl_intvec); |
2666 | EXPORT_SYMBOL(sysctl_jiffies); | 2869 | EXPORT_SYMBOL(sysctl_jiffies); |
2667 | EXPORT_SYMBOL(sysctl_ms_jiffies); | 2870 | EXPORT_SYMBOL(sysctl_ms_jiffies); |