Fix bug 1533, thanks to Hajime work. draft default tip
authorfrederic.urbani@inria.fr
Thu, 14 Feb 2013 17:54:13 +0100
changeset 1 cd5ead578b19
parent 0 bf005a4c1191
Fix bug 1533, thanks to Hajime work.
kernel345.patch
sim/sysctl.c
--- a/kernel345.patch	Mon Oct 15 11:31:49 2012 +0200
+++ b/kernel345.patch	Thu Feb 14 17:54:13 2013 +0100
@@ -1,3 +1,79 @@
+diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
+index 21d836f..8e8e47f 100644
+--- a/fs/proc/proc_sysctl.c
++++ b/fs/proc/proc_sysctl.c
+@@ -34,7 +34,7 @@ static struct ctl_table root_table[] = {
+ 	},
+ 	{ }
+ };
+-static struct ctl_table_root sysctl_table_root = {
++struct ctl_table_root sysctl_table_root = {
+ 	.default_set.dir.header = {
+ 		{{.count = 1,
+ 		  .nreg = 1,
+@@ -60,7 +60,7 @@ static void sysctl_print_dir(struct ctl_dir *dir)
+ 	printk(KERN_CONT "%s/", dir->header.ctl_table[0].procname);
+ }
+ 
+-static int namecmp(const char *name1, int len1, const char *name2, int len2)
++int namecmp(const char *name1, int len1, const char *name2, int len2)
+ {
+ 	int minlen;
+ 	int cmp;
+@@ -76,7 +76,7 @@ static int namecmp(const char *name1, int len1, const char *name2, int len2)
+ }
+ 
+ /* Called under sysctl_lock */
+-static struct ctl_table *find_entry(struct ctl_table_header **phead,
++struct ctl_table *find_entry(struct ctl_table_header **phead,
+ 	struct ctl_dir *dir, const char *name, int namelen)
+ {
+ 	struct ctl_table_header *head;
+@@ -310,7 +310,7 @@ static struct ctl_table *lookup_entry(struct ctl_table_header **phead,
+ 	return entry;
+ }
+ 
+-static struct ctl_node *first_usable_entry(struct rb_node *node)
++struct ctl_node *first_usable_entry(struct rb_node *node)
+ {
+ 	struct ctl_node *ctl_node;
+ 
+@@ -322,7 +322,7 @@ static struct ctl_node *first_usable_entry(struct rb_node *node)
+ 	return NULL;
+ }
+ 
+-static void first_entry(struct ctl_dir *dir,
++void first_entry(struct ctl_dir *dir,
+ 	struct ctl_table_header **phead, struct ctl_table **pentry)
+ {
+ 	struct ctl_table_header *head = NULL;
+@@ -340,7 +340,7 @@ static void first_entry(struct ctl_dir *dir,
+ 	*pentry = entry;
+ }
+ 
+-static void next_entry(struct ctl_table_header **phead, struct ctl_table **pentry)
++void next_entry(struct ctl_table_header **phead, struct ctl_table **pentry)
+ {
+ 	struct ctl_table_header *head = *phead;
+ 	struct ctl_table *entry = *pentry;
+@@ -846,7 +846,7 @@ static const struct dentry_operations proc_sys_dentry_operations = {
+ 	.d_compare	= proc_sys_compare,
+ };
+ 
+-static struct ctl_dir *find_subdir(struct ctl_dir *dir,
++struct ctl_dir *find_subdir(struct ctl_dir *dir,
+ 				   const char *name, int namelen)
+ {
+ 	struct ctl_table_header *head;
+@@ -948,7 +948,7 @@ failed:
+ 	return subdir;
+ }
+ 
+-static struct ctl_dir *xlate_dir(struct ctl_table_set *set, struct ctl_dir *dir)
++struct ctl_dir *xlate_dir(struct ctl_table_set *set, struct ctl_dir *dir)
+ {
+ 	struct ctl_dir *parent;
+ 	const char *procname;
 diff --git a/include/linux/slab.h b/include/linux/slab.h
 index a595dce..4a4dea3 100644
 --- a/include/linux/slab.h
--- a/sim/sysctl.c	Mon Oct 15 11:31:49 2012 +0200
+++ b/sim/sysctl.c	Thu Feb 14 17:54:13 2013 +0100
@@ -2,6 +2,7 @@
 #include <linux/mmzone.h>
 #include <linux/mman.h>
 #include <linux/ratelimit.h>
+#include <linux/proc_fs.h>
 #include "sim-assert.h"
 #include "sim-types.h"
 
@@ -157,57 +158,87 @@
 /**
  * Honestly, I don't understand half of that code.
  * It was modeled after fs/proc/proc_sysctl.c proc_sys_readdir
+ *
+ * Me either ;) (Hajime, Jan 2013)
  */
-static void iterate_recursive (const struct SimSysIterator *iter, struct ctl_table *table);
 
-static void iterate_table_recursive (const struct SimSysIterator *iter, struct ctl_table *table)
+/* from proc_sysctl.c (XXX) */
+extern struct ctl_table_root sysctl_table_root;
+void first_entry(struct ctl_dir *dir,
+                 struct ctl_table_header **phead, struct ctl_table **pentry);
+void next_entry(struct ctl_table_header **phead, struct ctl_table **pentry);
+struct ctl_table *find_entry(struct ctl_table_header **phead,
+                             struct ctl_dir *dir, const char *name, int namelen);
+struct ctl_dir *xlate_dir(struct ctl_table_set *set, struct ctl_dir *dir);
+/* for init_net (XXX, should be fixed) */
+#include <net/net_namespace.h>
+
+static void iterate_table_recursive (const struct SimSysIterator *iter, struct ctl_table_header *head)
 {
-  struct ctl_table *cur_table;
-  for (cur_table = table; cur_table->procname != NULL; cur_table++)
+  struct ctl_table *entry;
+
+  for (entry = head->ctl_table; entry->procname; entry++) 
     {
-      if (table->child == 0)
-	{
-	  bool may_read = (table->mode & MAY_READ);
-	  bool may_write = (table->mode & MAY_WRITE);
-	  int flags = 0;
-	  flags |= may_read?SIM_SYS_FILE_READ:0;
-	  flags |= may_write?SIM_SYS_FILE_WRITE:0;
-	  iter->report_file (iter, cur_table->procname, flags, (struct SimSysFile *)cur_table);
-	}
-      else
-	{
-	  iter->report_start_dir (iter, cur_table->procname);
-	  iterate_recursive (iter, table->child);
-	  iter->report_end_dir (iter);
-	}
+      bool may_read = (head->ctl_table->mode & MAY_READ);
+      bool may_write = (head->ctl_table->mode & MAY_WRITE);
+      int flags = 0;
+      flags |= may_read?SIM_SYS_FILE_READ:0;
+      flags |= may_write?SIM_SYS_FILE_WRITE:0;
+      iter->report_file (iter, entry->procname, flags, (struct SimSysFile *)entry);
     }
 }
 
-static void iterate_recursive (const struct SimSysIterator *iter, struct ctl_table *table)
+
+static void iterate_recursive (const struct SimSysIterator *iter, struct ctl_table_header *head)
 {
-  struct ctl_table_header *root = sysctl_head_next (NULL);
-  struct ctl_table_header *cur;
+  struct ctl_table_header *h = NULL;
+  struct ctl_table *entry;
+  struct ctl_dir *ctl_dir;
+
+  ctl_dir = container_of(head, struct ctl_dir, header);
+  for (first_entry(ctl_dir, &h, &entry); h; next_entry(&h, &entry)) 
+    {
+      struct ctl_dir *dir;
+      int ret;
 
-  iterate_table_recursive (iter, table);
-  for (cur = root; cur != 0; cur = sysctl_head_next (cur))
-    {
-      if (cur->set != table)
-	{
-	  continue;
-	}
-      iterate_table_recursive (iter, cur->root);
+      /* copy from sysctl_follow_link () */
+      if (S_ISLNK(entry->mode)) 
+        {
+          dir = xlate_dir(&init_net.sysctls, h->parent);
+          if (IS_ERR(dir))
+            {
+              ret = PTR_ERR(dir);
+              sim_assert (false);
+            }
+          else 
+            {
+              const char *procname = entry->procname;
+              h = NULL;
+              entry = find_entry(&h, dir, procname, strlen(procname));
+	      if (!entry) return;
+              ret = -ENOENT;
+            }
+        }
+
+      if (S_ISDIR(entry->mode))
+        {
+          iter->report_start_dir (iter, entry->procname);
+          iterate_recursive (iter, h);
+          iter->report_end_dir (iter);
+        }
+      else
+        {
+          iterate_table_recursive (iter, h);
+        }
     }
 
 }
 
 
-
 void sim_sys_iterate_files (const struct SimSysIterator *iter)
 {
-//	sim_assert (0);
-	return;
-  struct ctl_table_header *root = sysctl_head_next (NULL);
-  iterate_recursive (iter, root->ctl_table);
+  struct ctl_table_header *root = &sysctl_table_root.default_set.dir.header;
+  iterate_recursive (iter, root);
 }
 
 int sim_sys_file_read (const struct SimSysFile *file, char *buffer, int size, int offset)