Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.6.24-git22 /kernel/sysctl.c

Filename:/kernel/sysctl.c
Lines Added:279
Lines Deleted:90
Also changed in: (Previous) 2.6.24-git21  2.6.24-git20  2.6.24-git19  2.6.24-git18  2.6.24-git17  2.6.24-git16 
(Following) 2.6.24.3-rc1  2.6.24.3  2.6.24.4-rc1  2.6.24.4-rc2  2.6.24.4-rc3  2.6.24.4 

Location
[  2.6.24-git22
  [  kernel
     o  sysctl.c

Patch

diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c68f68d..d41ef6b 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -37,7 +37,6 @@
 #include <linux/highuid.h>
 #include <linux/writeback.h>
 #include <linux/hugetlb.h>
-#include <linux/security.h>
 #include <linux/initrd.h>
 #include <linux/times.h>
 #include <linux/limits.h>
@@ -53,6 +52,7 @@
 #ifdef CONFIG_X86
 #include <asm/nmi.h>
 #include <asm/stacktrace.h>
+#include <asm/io.h>
 #endif
 
 static int deprecated_sysctl_warning(struct __sysctl_args *args);
@@ -66,25 +66,27 @@ extern int sysctl_overcommit_memory;
 extern int sysctl_overcommit_ratio;
 extern int sysctl_panic_on_oom;
 extern int sysctl_oom_kill_allocating_task;
+extern int sysctl_oom_dump_tasks;
 extern int max_threads;
 extern int core_uses_pid;
 extern int suid_dumpable;
 extern char core_pattern[];
 extern int pid_max;
 extern int min_free_kbytes;
-extern int printk_ratelimit_jiffies;
-extern int printk_ratelimit_burst;
 extern int pid_max_min, pid_max_max;
 extern int sysctl_drop_caches;
 extern int percpu_pagelist_fraction;
 extern int compat_log;
 extern int maps_protect;
 extern int sysctl_stat_interval;
-extern int audit_argv_kb;
+extern int latencytop_enabled;
 
 /* Constants used for minimum and  maximum */
-#ifdef CONFIG_DETECT_SOFTLOCKUP
+#if defined(CONFIG_DETECT_SOFTLOCKUP) || defined(CONFIG_HIGHMEM)
 static int one = 1;
+#endif
+
+#ifdef CONFIG_DETECT_SOFTLOCKUP
 static int sixty = 60;
 #endif
 
@@ -156,8 +158,16 @@ static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *
 #endif
 
 static struct ctl_table root_table[];
-static struct ctl_table_header root_table_header =
-   { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) };
+static struct ctl_table_root sysctl_table_root;
+static struct ctl_table_header root_table_header = {
+   .ctl_table = root_table,
+   .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.header_list),
+   .root = &sysctl_table_root,
+};
+static struct ctl_table_root sysctl_table_root = {
+   .root_list = LIST_HEAD_INIT(sysctl_table_root.root_list),
+   .header_list = LIST_HEAD_INIT(root_table_header.ctl_entry),
+};
 
 static struct ctl_table kern_table[];
 static struct ctl_table vm_table[];
@@ -191,14 +201,6 @@ static struct ctl_table root_table[] = {
       .mode      = 0555,
       .child      = vm_table,
    },
-#ifdef CONFIG_NET
-   {
-      .ctl_name   = CTL_NET,
-      .procname   = "net",
-      .mode      = 0555,
-      .child      = net_table,
-   },
-#endif
    {
       .ctl_name   = CTL_FS,
       .procname   = "fs",
@@ -306,9 +308,43 @@ static struct ctl_table kern_table[] = {
       .procname   = "sched_nr_migrate",
       .data      = &sysctl_sched_nr_migrate,
       .maxlen      = sizeof(unsigned int),
-      .mode      = 644,
+      .mode      = 0644,
+      .proc_handler   = &proc_dointvec,
+   },
+   {
+      .ctl_name   = CTL_UNNUMBERED,
+      .procname   = "sched_rt_period_ms",
+      .data      = &sysctl_sched_rt_period,
+      .maxlen      = sizeof(unsigned int),
+      .mode      = 0644,
+      .proc_handler   = &proc_dointvec,
+   },
+   {
+      .ctl_name   = CTL_UNNUMBERED,
+      .procname   = "sched_rt_ratio",
+      .data      = &sysctl_sched_rt_ratio,
+      .maxlen      = sizeof(unsigned int),
+      .mode      = 0644,
       .proc_handler   = &proc_dointvec,
    },
+#if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP)
+   {
+      .ctl_name       = CTL_UNNUMBERED,
+      .procname       = "sched_min_bal_int_shares",
+      .data           = &sysctl_sched_min_bal_int_shares,
+      .maxlen         = sizeof(unsigned int),
+      .mode           = 0644,
+      .proc_handler   = &proc_dointvec,
+   },
+   {
+      .ctl_name       = CTL_UNNUMBERED,
+      .procname       = "sched_max_bal_int_shares",
+      .data           = &sysctl_sched_max_bal_int_shares,
+      .maxlen         = sizeof(unsigned int),
+      .mode           = 0644,
+      .proc_handler   = &proc_dointvec,
+   },
+#endif
 #endif
    {
       .ctl_name   = CTL_UNNUMBERED,
@@ -354,16 +390,6 @@ static struct ctl_table kern_table[] = {
       .mode      = 0644,
       .proc_handler   = &proc_dointvec,
    },
-#ifdef CONFIG_AUDITSYSCALL
-   {
-      .ctl_name   = CTL_UNNUMBERED,
-      .procname   = "audit_argv_kb",
-      .data      = &audit_argv_kb,
-      .maxlen      = sizeof(int),
-      .mode      = 0644,
-      .proc_handler   = &proc_dointvec,
-   },
-#endif
    {
       .ctl_name   = KERN_CORE_PATTERN,
       .procname   = "core_pattern",
@@ -382,15 +408,15 @@ static struct ctl_table kern_table[] = {
       .proc_handler   = &proc_dointvec_taint,
    },
 #endif
-#ifdef CONFIG_SECURITY_CAPABILITIES
+#ifdef CONFIG_LATENCYTOP
    {
-      .procname   = "cap-bound",
-      .data      = &cap_bset,
-      .maxlen      = sizeof(kernel_cap_t),
-      .mode      = 0600,
-      .proc_handler   = &proc_dointvec_bset,
+      .procname   = "latencytop",
+      .data      = &latencytop_enabled,
+      .maxlen      = sizeof(int),
+      .mode      = 0644,
+      .proc_handler   = &proc_dointvec,
    },
-#endif /* def CONFIG_SECURITY_CAPABILITIES */
+#endif
 #ifdef CONFIG_BLK_DEV_INITRD
    {
       .ctl_name   = KERN_REALROOTDEV,
@@ -462,14 +488,6 @@ static struct ctl_table kern_table[] = {
       .mode      = 0644,
       .proc_handler   = &proc_dointvec,
    },
-   {
-      .ctl_name   = KERN_PRINTK,
-      .procname   = "printk",
-      .data      = &console_loglevel,
-      .maxlen      = 4*sizeof(int),
-      .mode      = 0644,
-      .proc_handler   = &proc_dointvec,
-   },
 #ifdef CONFIG_KMOD
    {
       .ctl_name   = KERN_MODPROBE,
@@ -616,6 +634,15 @@ static struct ctl_table kern_table[] = {
       .mode      = 0644,
       .proc_handler   = &proc_dointvec,
    },
+#if defined CONFIG_PRINTK
+   {
+      .ctl_name   = KERN_PRINTK,
+      .procname   = "printk",
+      .data      = &console_loglevel,
+      .maxlen      = 4*sizeof(int),
+      .mode      = 0644,
+      .proc_handler   = &proc_dointvec,
+   },
    {
       .ctl_name   = KERN_PRINTK_RATELIMIT,
       .procname   = "printk_ratelimit",
@@ -633,6 +660,7 @@ static struct ctl_table kern_table[] = {
       .mode      = 0644,
       .proc_handler   = &proc_dointvec,
    },
+#endif
    {
       .ctl_name   = KERN_NGROUPS_MAX,
       .procname   = "ngroups_max",
@@ -683,6 +711,14 @@ static struct ctl_table kern_table[] = {
       .mode      = 0644,
       .proc_handler   = &proc_dointvec,
    },
+   {
+      .ctl_name   = CTL_UNNUMBERED,
+      .procname   = "io_delay_type",
+      .data      = &io_delay_type,
+      .maxlen      = sizeof(int),
+      .mode      = 0644,
+      .proc_handler   = &proc_dointvec,
+   },
 #endif
 #if defined(CONFIG_MMU)
    {
@@ -728,13 +764,40 @@ static struct ctl_table kern_table[] = {
       .ctl_name   = CTL_UNNUMBERED,
       .procname   = "softlockup_thresh",
       .data      = &softlockup_thresh,
-      .maxlen      = sizeof(int),
+      .maxlen      = sizeof(unsigned long),
       .mode      = 0644,
-      .proc_handler   = &proc_dointvec_minmax,
+      .proc_handler   = &proc_doulongvec_minmax,
       .strategy   = &sysctl_intvec,
       .extra1      = &one,
       .extra2      = &sixty,
    },
+   {
+      .ctl_name   = CTL_UNNUMBERED,
+      .procname   = "hung_task_check_count",
+      .data      = &sysctl_hung_task_check_count,
+      .maxlen      = sizeof(unsigned long),
+      .mode      = 0644,
+      .proc_handler   = &proc_doulongvec_minmax,
+      .strategy   = &sysctl_intvec,
+   },
+   {
+      .ctl_name   = CTL_UNNUMBERED,
+      .procname   = "hung_task_timeout_secs",
+      .data      = &sysctl_hung_task_timeout_secs,
+      .maxlen      = sizeof(unsigned long),
+      .mode      = 0644,
+      .proc_handler   = &proc_doulongvec_minmax,
+      .strategy   = &sysctl_intvec,
+   },
+   {
+      .ctl_name   = CTL_UNNUMBERED,
+      .procname   = "hung_task_warnings",
+      .data      = &sysctl_hung_task_warnings,
+      .maxlen      = sizeof(unsigned long),
+      .mode      = 0644,
+      .proc_handler   = &proc_doulongvec_minmax,
+      .strategy   = &sysctl_intvec,
+   },
 #endif
 #ifdef CONFIG_COMPAT
    {
@@ -808,6 +871,14 @@ static struct ctl_table vm_table[] = {
       .proc_handler   = &proc_dointvec,
    },
    {
+      .ctl_name   = CTL_UNNUMBERED,
+      .procname   = "oom_dump_tasks",
+      .data      = &sysctl_oom_dump_tasks,
+      .maxlen      = sizeof(sysctl_oom_dump_tasks),
+      .mode      = 0644,
+      .proc_handler   = &proc_dointvec,
+   },
+   {
       .ctl_name   = VM_OVERCOMMIT_RATIO,
       .procname   = "overcommit_ratio",
       .data      = &sysctl_overcommit_ratio,
@@ -910,7 +981,7 @@ static struct ctl_table vm_table[] = {
       .data      = &nr_overcommit_huge_pages,
       .maxlen      = sizeof(nr_overcommit_huge_pages),
       .mode      = 0644,
-      .proc_handler   = &proc_doulongvec_minmax,
+      .proc_handler   = &hugetlb_overcommit_handler,
    },
 #endif
    {
@@ -1081,6 +1152,19 @@ static struct ctl_table vm_table[] = {
       .extra1      = &zero,
    },
 #endif
+#ifdef CONFIG_HIGHMEM
+   {
+      .ctl_name   = CTL_UNNUMBERED,
+      .procname   = "highmem_is_dirtyable",
+      .data      = &vm_highmem_is_dirtyable,
+      .maxlen      = sizeof(vm_highmem_is_dirtyable),
+      .mode      = 0644,
+      .proc_handler   = &proc_dointvec_minmax,
+      .strategy   = &sysctl_intvec,
+      .extra1      = &zero,
+      .extra2      = &one,
+   },
+#endif
 /*
  * NOTE: do not add new entries to this table unless you have read
  * Documentation/sysctl/ctl_unnumbered.txt
@@ -1127,6 +1211,14 @@ static struct ctl_table fs_table[] = {
       .proc_handler   = &proc_dointvec,
    },
    {
+      .ctl_name   = CTL_UNNUMBERED,
+      .procname   = "nr_open",
+      .data      = &sysctl_nr_open,
+      .maxlen      = sizeof(int),
+      .mode      = 0644,
+      .proc_handler   = &proc_dointvec,
+   },
+   {
       .ctl_name   = FS_DENTRY,
       .procname   = "dentry-state",
       .data      = &dentry_stat,
@@ -1300,12 +1392,27 @@ void sysctl_head_finish(struct ctl_table_header *head)
    spin_unlock(&sysctl_lock);
 }
 
-struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev)
+static struct list_head *
+lookup_header_list(struct ctl_table_root *root, struct nsproxy *namespaces)
+{
+   struct list_head *header_list;
+   header_list = &root->header_list;
+   if (root->lookup)
+      header_list = root->lookup(root, namespaces);
+   return header_list;
+}
+
+struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces,
+                   struct ctl_table_header *prev)
 {
+   struct ctl_table_root *root;
+   struct list_head *header_list;
    struct ctl_table_header *head;
    struct list_head *tmp;
+
    spin_lock(&sysctl_lock);
    if (prev) {
+      head = prev;
       tmp = &prev->ctl_entry;
       unuse_table(prev);
       goto next;
@@ -1319,14 +1426,38 @@ struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev)
       spin_unlock(&sysctl_lock);
       return head;
    next:
+      root = head->root;
       tmp = tmp->next;
-      if (tmp == &root_table_header.ctl_entry)
-         break;
+      header_list = lookup_header_list(root, namespaces);
+      if (tmp != header_list)
+         continue;
+
+      do {
+         root = list_entry(root->root_list.next,
+               struct ctl_table_root, root_list);
+         if (root == &sysctl_table_root)
+            goto out;
+         header_list = lookup_header_list(root, namespaces);
+      } while (list_empty(header_list));
+      tmp = header_list->next;
    }
+out:
    spin_unlock(&sysctl_lock);
    return NULL;
 }
 
+struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev)
+{
+   return __sysctl_head_next(current->nsproxy, prev);
+}
+
+void register_sysctl_root(struct ctl_table_root *root)
+{
+   spin_lock(&sysctl_lock);
+   list_add_tail(&root->root_list, &sysctl_table_root.root_list);
+   spin_unlock(&sysctl_lock);
+}
+
 #ifdef CONFIG_SYSCTL_SYSCALL
 int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp,
           void __user *newval, size_t newlen)
@@ -1483,18 +1614,21 @@ static __init int sysctl_init(void)
 {
    int err;
    sysctl_set_parent(NULL, root_table);
-   err = sysctl_check_table(root_table);
+   err = sysctl_check_table(current->nsproxy, root_table);
    return 0;
 }
 
 core_initcall(sysctl_init);
 
 /**
- * register_sysctl_table - register a sysctl hierarchy
+ * __register_sysctl_paths - register a sysctl hierarchy
+ * @root: List of sysctl headers to register on
+ * @namespaces: Data to compute which lists of sysctl entries are visible
+ * @path: The path to the directory the sysctl table is in.
  * @table: the top-level table structure
  *
  * Register a sysctl table hierarchy. @table should be a filled in ctl_table
- * array. An entry with a ctl_name of 0 terminates the table. 
+ * array. A completely 0 filled entry terminates the table.
  *
  * The members of the &struct ctl_table structure are used as follows:
  *
@@ -1557,25 +1691,99 @@ core_initcall(sysctl_init);
  * This routine returns %NULL on a failure to register, and a pointer
  * to the table header on success.
  */
-struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
+struct ctl_table_header *__register_sysctl_paths(
+   struct ctl_table_root *root,
+   struct nsproxy *namespaces,
+   const struct ctl_path *path, struct ctl_table *table)
 {
-   struct ctl_table_header *tmp;
-   tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL);
-   if (!tmp)
+   struct list_head *header_list;
+   struct ctl_table_header *header;
+   struct ctl_table *new, **prevp;
+   unsigned int n, npath;
+
+   /* Count the path components */
+   for (npath = 0; path[npath].ctl_name || path[npath].procname; ++npath)
+      ;
+
+   /*
+    * For each path component, allocate a 2-element ctl_table array.
+    * The first array element will be filled with the sysctl entry
+    * for this, the second will be the sentinel (ctl_name == 0).
+    *
+    * We allocate everything in one go so that we don't have to
+    * worry about freeing additional memory in unregister_sysctl_table.
+    */
+   header = kzalloc(sizeof(struct ctl_table_header) +
+          (2 * npath * sizeof(struct ctl_table)), GFP_KERNEL);
+   if (!header)
       return NULL;
-   tmp->ctl_table = table;
-   INIT_LIST_HEAD(&tmp->ctl_entry);
-   tmp->used = 0;
-   tmp->unregistering = NULL;
-   sysctl_set_parent(NULL, table);
-   if (sysctl_check_table(tmp->ctl_table)) {
-      kfree(tmp);
+
+   new = (struct ctl_table *) (header + 1);
+
+   /* Now connect the dots */
+   prevp = &header->ctl_table;
+   for (n = 0; n < npath; ++n, ++path) {
+      /* Copy the procname */
+      new->procname = path->procname;
+      new->ctl_name = path->ctl_name;
+      new->mode     = 0555;
+
+      *prevp = new;
+      prevp = &new->child;
+
+      new += 2;
+   }
+   *prevp = table;
+   header->ctl_table_arg = table;
+
+   INIT_LIST_HEAD(&header->ctl_entry);
+   header->used = 0;
+   header->unregistering = NULL;
+   header->root = root;
+   sysctl_set_parent(NULL, header->ctl_table);
+   if (sysctl_check_table(namespaces, header->ctl_table)) {
+      kfree(header);
       return NULL;
    }
    spin_lock(&sysctl_lock);
-   list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
+   header_list = lookup_header_list(root, namespaces);
+   list_add_tail(&header->ctl_entry, header_list);
    spin_unlock(&sysctl_lock);
-   return tmp;
+
+   return header;
+}
+
+/**
+ * register_sysctl_table_path - register a sysctl table hierarchy
+ * @path: The path to the directory the sysctl table is in.
+ * @table: the top-level table structure
+ *
+ * Register a sysctl table hierarchy. @table should be a filled in ctl_table
+ * array. A completely 0 filled entry terminates the table.
+ *
+ * See __register_sysctl_paths for more details.
+ */
+struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
+                  struct ctl_table *table)
+{
+   return __register_sysctl_paths(&sysctl_table_root, current->nsproxy,
+               path, table);
+}
+
+/**
+ * register_sysctl_table - register a sysctl table hierarchy
+ * @table: the top-level table structure
+ *
+ * Register a sysctl table hierarchy. @table should be a filled in ctl_table
+ * array. A completely 0 filled entry terminates the table.
+ *
+ * See register_sysctl_paths for more details.
+ */
+struct ctl_table_header *register_sysctl_table(struct ctl_table *table)
+{
+   static const struct ctl_path null_path[] = { {} };
+
+   return register_sysctl_paths(null_path, table);
 }
 
 /**
@@ -1604,6 +1812,12 @@ struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
    return NULL;
 }
 
+struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
+                      struct ctl_table *table)
+{
+   return NULL;
+}
+
 void unregister_sysctl_table(struct ctl_table_header * table)
 {
 }
@@ -1889,26 +2103,6 @@ static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp,
    return 0;
 }
 
-#ifdef CONFIG_SECURITY_CAPABILITIES
-/*
- *   init may raise the set.
- */
-
-int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp,
-         void __user *buffer, size_t *lenp, loff_t *ppos)
-{
-   int op;
-
-   if (write && !capable(CAP_SYS_MODULE)) {
-      return -EPERM;
-   }
-
-   op = is_global_init(current) ? OP_SET : OP_AND;
-   return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
-            do_proc_dointvec_bset_conv,&op);
-}
-#endif /* def CONFIG_SECURITY_CAPABILITIES */
-
 /*
  *   Taint values can only be increased
  */
@@ -2293,7 +2487,7 @@ static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp
    pid_t tmp;
    int r;
 
-   tmp = pid_nr_ns(cad_pid, current->nsproxy->pid_ns);
+   tmp = pid_vnr(cad_pid);
 
    r = __do_proc_dointvec(&tmp, table, write, filp, buffer,
                 lenp, ppos, NULL, NULL);
@@ -2322,12 +2516,6 @@ int proc_dointvec(struct ctl_table *table, int write, struct file *filp,
    return -ENOSYS;
 }
 
-int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp,
-         void __user *buffer, size_t *lenp, loff_t *ppos)
-{
-   return -ENOSYS;
-}
-
 int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp,
           void __user *buffer, size_t *lenp, loff_t *ppos)
 {
@@ -2662,6 +2850,7 @@ EXPORT_SYMBOL(proc_dostring);
 EXPORT_SYMBOL(proc_doulongvec_minmax);
 EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
 EXPORT_SYMBOL(register_sysctl_table);
+EXPORT_SYMBOL(register_sysctl_paths);
 EXPORT_SYMBOL(sysctl_intvec);
 EXPORT_SYMBOL(sysctl_jiffies);
 EXPORT_SYMBOL(sysctl_ms_jiffies);


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.