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

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

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

Filename:/kernel/sysctl.c
Lines Added:226
Lines Deleted:32
Also changed in: (Previous) 2.6.24-git5  2.6.24-git4  2.6.24-git3  2.6.24-git2  2.6.24  2.6.24-rc8 
(Following) 2.6.24-git7  2.6.24-git8  2.6.24-git9  2.6.24-git10  2.6.24-git11  2.6.24-git12 

Location
[  2.6.24-git6
  [  kernel
     o  sysctl.c

Patch

diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c68f68d..4bc8e48 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -81,6 +81,7 @@ 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
@@ -156,8 +157,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 +200,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 +307,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,
@@ -382,6 +417,15 @@ static struct ctl_table kern_table[] = {
       .proc_handler   = &proc_dointvec_taint,
    },
 #endif
+#ifdef CONFIG_LATENCYTOP
+   {
+      .procname   = "latencytop",
+      .data      = &latencytop_enabled,
+      .maxlen      = sizeof(int),
+      .mode      = 0644,
+      .proc_handler   = &proc_dointvec,
+   },
+#endif
 #ifdef CONFIG_SECURITY_CAPABILITIES
    {
       .procname   = "cap-bound",
@@ -728,13 +772,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
    {
@@ -1300,12 +1371,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 +1405,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 +1593,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 +1670,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 +1791,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)
 {
 }
@@ -2662,6 +2855,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.